Проблема оптимизации приложения React-Redux-Reselect - PullRequest
0 голосов
/ 09 мая 2019

Я использую React и Redux только несколько месяцев и недавно внедрил Реселект, чтобы попытаться сделать приложение быстрее.Я не могу заставить его работать так, как мне хотелось бы, и я не уверен, откуда возникла проблема.

Я возобновил разработку приложения планирования для отдела разработки, в котором я работаю.Главная страница может иметь определенное количество недель, содержащихся в Row.Каждый день недели является Компонентом, и в каждом Day Компоненте у вас может быть TimePlanned Компонент.Существует одна Row строка Компонента на заявку, затрагиваемая разработчиком, и может быть до 10 заявок на пользователя, поэтому ... Компонентов много.

Я реализовал Reselect таким образом, чтобы мои многие подключенные Компоненты перерисовывались не так часто, как это было раньше с Redux.

У меня проблема с Day Component.Я пытаюсь получить от них доступ к как можно меньшему количеству данных, чтобы предотвратить повторный рендеринг других Day, когда они не обеспокоены изменением.

Вот какие данные я хочу получить 'sort 'может выглядеть так:

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 - это всегда число, но если мои плановые операции отсортированы по проектам, он будет эквивалентен идентификатору проекта.Цель запомненного селектора - вернуть объект planifications, соответствующий идентификатору, переданному в реквизитах.

В этом примере мой фильтр установлен пользователем.Я бы хотел, чтобы Row из моих Day компонентов получил доступ к планированию только с '3' userId.

В моем 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 Ответ

1 голос
/ 15 июня 2019

Я проверил ваш код, и есть очень немного вещей, которые могут быть полезны:

1. getGroup селектор должен быть запомнен, потому что после каждого обновления магазина _.find будетверните новый массив, и памятка для makeGetRelevantObjectPlans будет нарушена.

Так что getGroup может выглядеть так:

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

const getGroup = createSelector(
  [groupBy],
  (groupBy) => _.find(groupBy, ['isActive', true]),
);
Также может быть полезно использование createStructuredSelector вместо makeMapStateToProps
...