React / Redux контролирует когда рендерится функциональный компонент - PullRequest
0 голосов
/ 14 мая 2019

У меня проблема с обновлением приложения.В моем редукторе у меня есть интересующее действие checkTasks.Это ничего не значит, checkTasks просматривает мой список текущих задач, и если срок их выполнения истек, он удаляет их из массива tasks, чтобы поместить их в массив expiredTasks.Моя проблема в том, что в большинстве случаев checkTasks ничего не делает, только иногда.Но каждый раз, когда вызывается checkTasks, мой компонент обрабатывается.

mapStateToProps моего компонента выглядит так:

const mapStateToProps = (_state) => {
    return {
        tasks: _state.tasksState
    }
}

, и мой компонент заботится о 2 атрибутах из состояния:

function Tasts({ tasksState: _tasksState}){
    ...
    return <>
        {renderExpired(_tasksState.expiredTasks)}
        {renderTasks(_tasksState.tasks)}
    </>
}

редуктор

const reducer(_state = { tasks: [], expiredTasks: [] }, _action){
    const newState = { ..._state };
    ...
    case 'checkTasks':
            for (let i = newState.tasks.length - 1; i >= 0; i--) {
                if (isExpired(newState.tasks[i])) {
                    newState.expiredTasks.push(newState.tasks.splice(i, 1)[0]);
                }
            }
        break;

    ...

    return newState;
}

Что я замечаю, так это то, что каждый раз (один раз в секунду) вызывается действие checkTasks, мой компонент перезапускается, даже если практически информацияв expiredTasks и tasks не изменилось.

Если бы я мог изменить свой mapStateToProps на что-то вроде

const mapStateToProps = (_state) => {
    return {
        tasks: _state.tasksState.tasks,
        expiredTasks: _state.tasksState.expiredTasks
    }
}

Это, вероятно, остановило бы постоянные обновления, однако, чтокажется, ломает все обновления.Включая задачи, перемещающиеся из одного массива в другой.Я не знаю, есть ли способ сказать, чтобы redux NOT запускал обновление от редуктора, хотя это, вероятно, анти-паттерн.Я также пытаюсь не проходить через shouldComponentUpdate, учитывая, что для оценки того, должен ли я обновить , может потребоваться проверка двух массивов объектов друг против друга.Во-первых, проще не запускать обновление, чем сравнивать несколько массивов.

1 Ответ

1 голос
/ 14 мая 2019

Так что, если вы используете redux-thunk, вы действительно можете улучшить логику внутри создателей действий. В этом случае мы собираемся проверить, не истек ли срок выполнения каких-либо задач, фактически перетаскивая данные вашего редуктора в нашего создателя действий. Затем, применяя очень похожую логику к тому, что вы уже делаете, мы решим, действительно ли мы отправим новое действие.

const checkTasks = () => {
    return (dispatch, getState) => {
       const currentState = getState().yourReducer //your reducer key goes here. Returns its current state
       const expiredTasks = [] 

       for(let i = currentState.tasks.length - 1; i >= 0; i--){
          if(isExpired(currentState.tasks[i]){ //remember to import your isEmpty() logic
               expiredTasks.push(currentState.tasks[i])
          }
       }

       if(expiredTasks.length > 0){
          dispatch({
             type: "checkTasks"
          })
       }

   }
}

Если expiredTasks пустые, мы не будем отправлять никаких действий. Нет действий, значит нет обновления редуктора. Что означает отсутствие повторного рендеринга компонентов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...