美文网首页react.js
使用reselect注意事项

使用reselect注意事项

作者: Yong_bcf4 | 来源:发表于2020-11-09 09:53 被阅读0次

    为什么使用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中所绑定的函数

    相关文章

      网友评论

        本文标题:使用reselect注意事项

        本文链接:https://www.haomeiwen.com/subject/socrbktx.html