react.js

使用reselect注意事项

2020-11-09  本文已影响0人  Yong_bcf4

为什么使用reselect

react-redux的概念中,将组件分为容器组件与视图组件

react-redux中的通过connect将容器组件与视图组件连接起来。

connect(mapStateToProps, mapDispatchToProps)(View)

mapStateToProps mapStateToProps是一个函数,函数返回一个需要通过props传递给视图组件的对象,

const mapStateToProps = (state, props) => {
  // state一改变我就要取值
  return {
    todos: [1,2,3]
  }
}

mapDispatchToProps 用来建立视图组件的参数到store.dispatch方法的映射。它定义了哪些用户的操作应该当作Action

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch({
        type: 'SET_VISIBILITY_FILTER',
        filter: ownProps.filter
      });
    }
  };
}

在容器组件中,每次reducers中的state变更的时候(任何state包括其他模块的state),都会触发mapStateToProps所在的函数,如果项目规模比较大,并且在mapStateToProps中进行一些计算的时候,就会增加计算量,影响项目的运行效率。因此我们引入了reselect

如何使用reselect

reselect可以对传入的依赖做一个缓存,如果传入的函数的结果不变,那返回的结果也不会变

reselect使用方式

const mySelector = createSelector(
  state => state.values.value1,
  state => state.values.value2,
  (value1, value2) => value1 + value2
)

// 也能把第一个参数作为一个数组
const totalSelector = createSelector(
  [
    state => state.values.value1,
    state => state.values.value2
  ],
  (value1, value2) => value1 + value2
)

举个例子

import { createSelector } from 'reselect'

const getPageA = state => {
    // state一改变我就要取值
    return state.pageB.get('number')
} 

const getPageAObj = state => {
    // state一改变我就要取值
    return state.pageB.getIn(['obj'])
} 

const selectorProps = createSelector([getPageA, getPageAObj], (number, nameObj) => {
    // number与nameObj变更了后我才计算下面的,要是没变的话直接返回上次的值
    return {
        number:dealNumber(number)
    }
})

export default connect(selectorProps, actionCreator)(View)

如上的例子,在state变更的时候,就会触发getPageAgetPageAObj函数。如果createSelector依赖的这两个函数的结果没有变更,那就不会执行dealNumber相关的操作,而是直接返回上次已经计算好的结果。

总结:

  1. 在容器组件中采用createSelector对计算进行缓存

  2. 在依赖函数中只直接取值,不针对值进行计算,将计算放到createSelector中最后一个参数的函数中。

  3. createSelector中的依赖结果值要唯一,如果采用了Immutable结构,不能在依赖函数中执行toJS()方法。因为toJS()每次都返回一个新的对象, createSelector内部采用===做简单比较

  4. 如果采用了Immutable对数据进行了包装,那state中某个属性变更后返回的都是一个新的state, 这样在 createSelector中的依赖函数所返回的值都将是一个新的值,也将会触发相关的重新计算。如果计算量比较大的话,可以考虑将state拆分成多个子state, 再通过combineReducers组合起来。否则createSelector也就不起作用了。

!> 注意:关于state变更。如果有pageApageB,通过reduxcombineReducers方法将pageApageB合并成一个大的state,更改了pageA中的state的时候,也会触发pageB中所绑定的函数

上一篇 下一篇

猜你喜欢

热点阅读