React / Redux控制何时渲染功能组件

时间:2019-05-14 03:07:55

标签: javascript reactjs redux

我遇到了我的应用程序更新过多的问题。在我的减速器中,我有一个感兴趣的动作checkTasks。它并没有太大的作用,checkTasks浏览了我当前的任务列表,如果它们中的任何一个过期了,它就会将它们从tasks数组中删除,然后将它们放入expiredTasks数组中。我的问题是,在{em>大部分时间中,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动作,即使实际上expiredTaskstasks中的信息没有被调用,我的组件也会重新渲染。改变了。

如果我可以将mapStateToProps更改为

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

这可能会停止不断的刷新,但是,这似乎破坏了所有刷新。包括从一个阵列移动到另一个阵列的任务。我不知道是否有办法告诉redux NOT 从reducer触发更新,尽管这可能是一种反模式。 考虑到评估我是否应该更新可能需要相互检查2个对象数组,因此我也尝试不走过shouldComponentUpdate。首先不必触发更新,比必须比较多个数组要容易得多。

1 个答案:

答案 0 :(得分:1)

因此,如果您正在使用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为空,那么我们将不发送任何操作。没有动作,则意味着没有减速器更新。这意味着无需重新渲染组件。