资讯专栏INFORMATION COLUMN

React学习开发经验总结分享

Ajian / 263人阅读

摘要:代替我们做了下面例子中函数做的事情相关链接使用内联函数与传递的问题在中使用内联函数在方法里面定义的函数并通过传递到子组件是很方便的,但是这样用也会影响应用的性能。

Immutability Helper

这是react官方文档推荐的方法(源代码很少)
一般的state,例如层级比较浅的,可以直接用Object.assign或者...(扩展语法来解构),但是在层级比较深,或者操作数组的情况下reducer写起来就要麻烦些,这时候就可以用immutability helper的update方法了

//更新数组中的某一条数据
updatePurchaseDetail(state, { index, payload }) {
      return update(state, {
        purchaseDetails: {
          [index]: {
            $merge: payload
          }
        }
      })
    },
//向数组中添加一条数据 遵循不可变数据结构 我们不能直接用Push
addPurchaseLine(state, { item }) {
      return update(state, {
        purchaseDetails: {
          $push: [item]
        }
      })
    },
const collection = [1, 2, {a: [12, 17, 15]}];
const newCollection = update(collection, {
    2: {
      a: {
        $splice: [[1, 1, 13, 14]] // [1,1,13,14]对应于数组的splice函数的参数
      }
    }
  }
);
// => [1, 2, {a: [12, 13, 14, 15]}] 
// 在collection数组索引2的对象的a属性的数组的索引1的位置插入13,14
考虑使用函数式的setState

react官方文档中这样介绍setState的

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

setState不会立即修改this.state,也就是说我们在调用setState的后,立即访问this.state是不能取得最新的this.state的值的。这样在一些特殊需求的时候可能会出现问题。但是我们可以通过使用setState回调函数的形式来使下面的代码拿到最新的this.state的值。

updateState({target}) {
   this.setState(prevState => {
     const updatedUser = {...prevState.user, [target.name]: target.value}; // 使用先前的state来构建新的state的值
     doSomething(updatedUser); 
     return { user: updatedUser }; 
   });
 }
使用PureComponent

大家都知道使用好shouldComponentUpdate 可以优化性能,对props 和 state 的所有属性进行比较来决定组件是否需要更新, 这个函数默认都是返回true,也就是说需要更新。当我们严格遵守不可变数据结构的时候,就可以继承React.PureComponent来对props和state进行浅比较来决定组件是否应该更新,方便的优化我们组件的性能。PureComponent代替我们做了下面例子中shouldComponentUpdate函数做的事情.相关链接

class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    return (
      
    );
  }
}
使用内联函数与传递props的问题

在react中使用内联函数(在render方法里面定义的函数,并通过props传递到子组件)是很方便的,但是这样用也会影响应用的性能。
影响性能的原因主要有两个
1.会经常触发垃圾回收机制
2.一个内联函数每次都是一个新的引用,也就是说每次都会触发子组件的render函数(这个时候使用PureComponent就无效了)

class MyComponent extends React.Component {
  render() {
    const msg = "Hello " + this.props.user.name.first;
    return  this.props.onAlert(msg)} />;
    //另一种形式 this.props.onAlert.bind(this, msg)
  }
}

如何避免使用inline function
1.可以把数据绑定在元素上

...
//同一个函数需要处理多种情况的时候
handleClick = (ev) => {
  const { action } = ev.target.dataSet
  this.props.dispatch({
    type: "handleBpm",
    action
  })
}
...
  
  

2.把事件处理函数移到子组件

// 父组件
...
render () {
  const msg = "Hello " + this.props.user.name.first;
  return (
    
  )
}
// 子组件 PureChild
handleClick = () => {
  //do something
  const { onAlert, msg } = this.props;
  onAlert(msg)
}
...
render () {
  return (
    ...
    
) }

第二种方法需要我们在可以编码子组件的情况下才可以做到
还有一种通过babel插件reflective-bind的方式可以参考
不只是内联函数,我们在render函数里面应该尽可能少的声明实例,尽量不把在render里生成的实例当做Props传递下去。

区分Container与Component

Container与Component的主要区别在于:

1.Container是跟全局状态有关联的,通常被用来管理数据并通过connect函数连接到全局state,几乎不写样式
2.Component与样式联系紧密,但是不参与管理任何数据,只通过接收到的props响应数据更改

在dva中routes下面的文件目录相当于containers,也就是说我们需要使用connect的组件就应该规划在这里面。
component文件目录就应该放置与全局state无关,可以复用的通用组件。

另外每一个文件夹的入口文件可以用index.js命名,这样有两个明显的好处。第一点是可以让阅读代码的人,一眼就知道在当前目录下,哪个文件是入口文件。第二点是在其他文件Import目标文件的时候,只需要写到folderName的位置就可以了。webpack会自动读取当前文件目录下的index文件。
例如import Home from routes/home 而不用写成import Home from routes/home/index

关于react规范结构的问题 可以参考
how to scale react applications
react-boilerplate
Airbnb React 编码规范

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89673.html

相关文章

  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    ermaoL 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    kamushin233 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    yy736044583 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    awokezhou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<