Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 功能组件渲染时的反应/重演控制_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript 功能组件渲染时的反应/重演控制

Javascript 功能组件渲染时的反应/重演控制,javascript,reactjs,redux,Javascript,Reactjs,Redux,我的应用程序更新太多,出现了这个问题。在我的reducer中,我有一个感兴趣的动作checkTasks。它没什么作用,checkTasks浏览我的当前任务列表,如果其中任何任务过期,它会将它们从tasks数组中删除,以将它们放入expiredTasks数组中。我的问题是,大多数时候,checkTasks什么都不做,只是有时候。但是每次调用checkTasks时,我的组件都会被渲染 我的组件的MapStateTrops如下所示: const mapStateToProps = (_state) =

我的应用程序更新太多,出现了这个问题。在我的reducer中,我有一个感兴趣的动作
checkTasks
。它没什么作用,
checkTasks
浏览我的当前任务列表,如果其中任何任务过期,它会将它们从
tasks
数组中删除,以将它们放入
expiredTasks
数组中。我的问题是,大多数时候,
checkTasks
什么都不做,只是有时候。但是每次调用
checkTasks
时,我的组件都会被渲染

我的组件的
MapStateTrops
如下所示:

const mapStateToProps = (_state) => {
    return {
        tasks: _state.tasksState
    }
}
我的组件关心状态的两个属性:

function Tasts({ tasksState: _tasksState}){
    ...
    return <>
        {renderExpired(_tasksState.expiredTasks)}
        {renderTasks(_tasksState.tasks)}
    </>
}
我注意到的是,每次(每秒一次)调用
checkTasks
操作时,我的组件都会重新加载,即使
expiredTasks
tasks
中的信息实际上没有改变

如果我可以将我的
MapStateTops
更改为

const mapStateToProps = (_state) => {
    return {
        tasks: _state.tasksState.tasks,
        expiredTasks: _state.tasksState.expiredTasks
    }
}
这可能会停止不断的刷新,然而,这似乎打破了所有刷新。包括从一个阵列移动到另一个阵列的任务。我不知道是否有办法告诉redux不要触发来自reducer的更新,尽管这可能是一种反模式。
考虑到评估是否应该更新可能需要相互检查两个对象数组,我也尽量不使用
shouldComponentUpdate
。首先不触发更新要比比较多个数组容易得多。

因此,如果您使用redux thunk,您可以真正增强动作创建者内部的逻辑。在本例中,我们将通过实际将reducer数据拉入action creator来检查是否有任何任务已过期。然后将非常相似的逻辑应用到您已经在做的事情中,我们将决定是否实际发送一个新动作

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为空,则我们不会发送任何操作。没有动作,意味着没有减速器更新。这意味着没有组件重新渲染。

我认为最好的选择是修改调用动作创建者的内容。你能分享你的动作创建者代码和它的分派吗?@ChristophenGo动作创建者正在
setInterval(checkTasks,1000)
上被调用。我知道每秒调用action creator非常快,但是否无法进行重复操作,也无法不更新状态不受影响的组件?如果更新reducer状态,组件将始终被重新渲染。解决这个问题的方法是修改动作创建者,以确定是否需要发送动作。与我们分享你的行动创造者的样子like@ChristopherNgo我应该在什么州这样做?在间隔回调本身中?或者,如果我没有更改任何内容,我就不能从reducer触发更新吗?您可以在action creator逻辑内部执行此检查。如果你有一个单独的动作创建者文件,我们会在那里修复它。我们会要求派遣,或者不派遣行动。是的,我刚刚想到用我的传奇故事来代替,但是谢谢你的例子,所以我可以给你信用!该死的,我相信你也可以在你的传奇实现中应用非常相似的思维过程
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"
          })
       }

   }
}