优化React-Redux-Reselect应用程序的问题

时间:2019-05-09 15:04:19

标签: reactjs react-redux lodash reselect

我使用React和Redux仅仅几个月了,最近我实现了Reselect,以尝试使应用程序更快。我无法使其按我希望的方式工作,而且我不确定问题来自何方。

我继续为我工作的开发部门开发Planning应用程序。主页可以包含Row中包含的特定星期数。一周中的每一天都是一个组件,在每个Day组件中,您可能都有一个TimePlanned组件。对于开发人员而言,每张票证有一个Row组件行,每位用户最多可以有10张票证,因此...有很多组件。

我实现了Reselect,以使我连接的许多组件不会像以前使用Redux那样频繁地重新渲染。

Day组件有问题。我试图让他们访问尽可能少的数据,以防止其他Day在他们不关心更改时重新呈现。

这就是我要“排序”的数据的样子:

planifie:{
   tickets : {
     29859 : {
       ticketId : 29859,
       typeId : 1,
       projectId : 6,
       userId : 3;
       planifications : [549],
       comments : []
     }
   },
   planifications : {
      549 : {
         planId : 549,
         ticketId : 29859,
         planDate : "2019-05-16",
         planTime : 480,
         userId : 3
      },
      550 : {
         planId : 550,
         ticketId : 29859,
         planDate : "2019-05-16",
         planTime : 480,
         userId : 6
      }
   },
   users : {
      3 : {
       userId : 3,
       userName : "pdupont",
       tickets : [29859],
       comments : [],
       planifications : [549]
      }
   }
}

每个“类别”当然都有几条记录。

我的选择器如下:

export const getAllPlans = state => state.planifie.planifications
export const getGroup = state =>  _.find(state.filters.plannedFilters.groupBy, ['isActive', true])
export const getUserPropsId = (state,props) => props.userId

export const makeGetAllPlans = () => {
    return createSelector(
        getAllPlans,
        plans => plans
    )
}

export const makeGetRelevantObjectPlans = () => {
    return createSelector(
        [getAllPlans,getGroup,getUserPropsId],
        (planifications,group,user) => {
            switch (group.code) {
                case 'project':
                    return _.filter(planifications, {projectId : user})
                case 'user':
                    return _.filter(planifications, {userId : user})
                case 'type':
                    return _.filter(planifications, {typeId : user})
            }
        }
    )
}

props.userId始终是数字,但是如果我的计划按项目进行排序,则它等效于projectId。记忆选择器的目标是返回与传递给道具的ID相关的planifications对象。

在此示例中,我的过滤器是按用户过滤的。我希望Row组件中的Day只访问用户ID为'3'的规划。

在我的Day组件中,这就是调用选择器的方式:


const makeMapStateToProps = () => {
    const getComs = makeGetRelevantComments()
    const getPlans = makeGetRelevantPlans()
    const getPlanifications = makeGetRelevantObjectPlans()
    const mapStateToProps = (state, props) => {
        return {
            coms : getComs(state,props),
            plans : getPlans(state,props),
            planifications : getPlanifications(state,props)
        }
    }
    return mapStateToProps
}

const mapDispatchToProps = (dispatch) => (
    bindActionCreators(ActionsCreators, dispatch)
)

export default connect(makeMapStateToProps, mapDispatchToProps)(Day)

我在componentDidUpdate()中放置了一个函数,以查看触发重新渲染的原因,并且在每个Day组件上,甚至使用不同props.userId的组件,planifications都进行了重新渲染,所以我的页面需要很长时间才能加载。

例如,如果我通过Redux减速器操作更新一个计划的日期:

case types.SET_PLAN:
            return {
                ...state,
                planifie: {
                    ...state.planifie,
                    planifications : {
                        ...state.planifie.planifications,
                        [action.data.planId] : {

                 ...state.planifie.planifications[action.data.planId],
                            ...action.data.plan
                        }
                    }
                },
                isLoading: false
            }

然后重新渲染我的“每日组件”中的每个组件。

我想知道我的代码中是否丢失了某些东西,是否误解了记住的选择器可以做什么,lodash filter函数是否阻止了代码的不变性,或者我的数据不是格式化为这种类型的东西。

谢谢。

1 个答案:

答案 0 :(得分:1)

我遍历了您的代码,几乎没有什么可以帮助您的:

1。getGroup选择器必须被记录,因为每次存储_.find更新后将返回新的数组,并且makeGetRelevantObjectPlans的记录将被破坏。 / p>

所以getGroup可能像这样:

const groupBy = state => state.filters.plannedFilters.groupBy;

const getGroup = createSelector(
  [groupBy],
  (groupBy) => _.find(groupBy, ['isActive', true]),
);
  1. 使用sample code in the official docs代替makeMapStateToProps可能也会有帮助