【问题标题】:react/redux state and components useState become out of sync on fast clickingreact/redux 状态和组件 useState 在快速点击时变得不同步
【发布时间】:2021-04-14 09:13:21
【问题描述】:

编辑:代码顺序的格式:

好的。所以我试图找出为什么会发生这种情况......

情况是:

我有一个组件,其中列出了一堆 div,如果它们被选中,这些 div 会亮起绿色……所选 div 的集合存储在 LogicSlice.producitonMachineSelected[] 中。 然而,如果我点击快速 - 事情会变得......很奇怪。

有问题的组件是:

function MachineCard(props) {
    const data = props.props;
    const [checked, setChecked] = useState(false);
    const [machineCardColor, setMachineCardColor] = useState("#7070ff");
    const dispatch = useDispatch();
    useEffect(()=>{
        console.log("checkedChanged",checked);
        checked? setMachineCardColor("#70ff70"):setMachineCardColor("#7070ff");

    },[checked])
    return(
        <div className="MachineCard" 
            style={{backgroundColor:machineCardColor}}onClick={()=>{
                setChecked(!checked);
                dispatch(setProductionMachinesSelected(data.machineID))

            }
         }>
       </div>

}


逻辑切片内部的 reducer,它是使用 redux 工具包中的 CreateSlice 制作的……它允许不可变更新……下面也是手工编写的不可变代码……但它会导致同样的问题…… . 所以我有理由确定这不是错误的来源。

        setProductionMachinesSelected:(state,action)=>{
            const machineID = action.payload;
            const found = state.productionMachinesSelected.find(x=>x===machineID);
            if(found){
                state.productionMachinesSelected = state.productionMachinesSelected.filter(x=>x.machineID===machineID)
           }else{
                state.productionMachinesSelected.push(machineID);
           }
            return state;
        }

此代码的问题 - 每次调度都会发生 setChecked - 但如果点击太快就会变得不同步。

我试过把dispatch放到机器卡的useEffect中

//this does not work.
    useEffect(()=>{
        console.log("checkedChanged",checked);
        checked? setMachineCardColor("#70ff70"):setMachineCardColor("#7070ff");
        dispatch(setProductionMachinesSelected(data.machineID))

    },[checked])

我尝试过更改顺序...但它不仅会变得不同步...如果单击快速...它似乎会完全擦除 producitonMachinesSelected 数组。

管理状态的 redux 工具包检查器也反映了这些疯狂的变化......

真的,我只是想确保 div 的颜色与它在 redux 商店中的状态相匹配......为什么会这样?

至于我的意思是剧烈变化。

the redux state change list
state1: [1]
state2:[1,4,5,6,7,8]
state3:[]
state4:[2,3,4]
state5:[3,4]
state6:[]

// the useState of the components are also doing their own thing independent of this.

我认为这不应该发生 - 如果每个操作实际上是按照我点击它们的顺序执行的,那么无论我点击多快 - 它们不应该只是上面代码中的一次状态更改吗? - 即使显示级联变化需要更长的时间?

编辑:根据建议在减速器中尝试以下操作: 无济于事:(它在 redux 工具包的创建切片中)

const machineID = action.payload;
const found = state.productionMachinesSelected.find(x=>x===machineID);
const newState = found?
    {...state,productionMachinesSelected:state.productionMachinesSelected.filter(x=>x.machineID===machineID)}
    :
    {...state,productionMachinesSelected:[...state.productionMachinesSelected, machineID]};
return newState;

所以...发生了什么事? 更新:

修改了模式,而不是使用本地状态,从 redux 存储中读取状态...这导致与状态保持同步...但是///

如果你点击得足够快......状态会损坏。

双击一个 div 会擦除整个数组,只在数组中留下一个 div...这是奇怪的数组跳过行为...无论我是否将 reducer 编写成不可变的,都会发生这种情况。

【问题讨论】:

  • 我必须解决这个问题的一个想法?如果问题在于处理陈旧更新的reducer,而不是一个数组,一个带有machineID键的对象,它只存储一个bool......所以过滤器失败的机会......根本无法扩展。跨度>
  • 它使用的是 redux 工具包中的创建切片,我认为它使用 immer... 应该是不可变的更新...除非数组方法不起作用?
  • 并且没有...手动重写为 100% 不可变...根本不会改变结果...仍然非常不理想。
  • 你调度了一个名为 setProductionMachinesSelected 的减速器,并且在减速器中你改变了状态???发布的代码没有意义。什么是 setMachineCardColor?您是否正在将 redux 状态复制到本地状态并尝试同时管理两者?
  • 我正在使用 reduxTool 工具包中的 createSlice... 它使用 immer... 允许将状态变异代码转换为非变异代码。 - 我已经用不可变版本编辑了问题 - 问题完全相同,因此我不认为这是问题所在。

标签: javascript node.js reactjs redux


【解决方案1】:

好吧...我是个笨蛋...

事实证明......它根本不是快速点击。只需单击即可删除项目...

问题源于两件事......

1:当我真的只需要一种状态时,我使用了两种状态... 2:reducer 中的代码有错误...我有一个数字数组...但过滤器就像是一个机器对象...不是 MachineId 的列表...因此:

            const machineID = action.payload;
            const found = state.productionMachinesSelected.find(x=>x===machineID); 
 
            if(found){
                 state.productionMachinesSelected = state.productionMachinesSelected.filter(x=>x!==found)//here was the error... before it was x.machineID===machineID... the x is a number and not an object

           }else{
                state.productionMachinesSelected.push(machineID);

           }
           state.productionMachinesSelected.sort((a,b)=>a-b);
            return state;

现在可以完美运行了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2017-11-15
    • 2021-12-30
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多