【问题标题】:My reducer is triggered twice when I call it once. There something strange when I try to fix it当我调用一次时,我的减速器被触发了两次。当我尝试修复它时有一些奇怪的东西
【发布时间】:2021-04-25 01:06:23
【问题描述】:

这里是my code。 演示站点是here

在演示网页上,我有 2 个按钮,1 个是“开始”按钮,另一个是“返回”按钮。假设当我点击“go”按钮时,当前值会以如下格式显示在控制台中:

before:{"a":[12,27],"b":[63,14]}
after:{"a":[75,27],"b":[63,14]}

不幸的是,实际结果如下:

before:{"a":[12,27],"b":[63,14]}
after:{"a":[75,27],"b":[63,14]}
before:{"a":[12,27],"b":[63,14]}
after:{"a":[75,27],"b":[63,14]}

当我在DEF 组件中评论以下行时:

setTimeout(()=>{
  setContextValue({undoUtil});
},10)

然后,当前值将以正确的格式显示在控制台中。 但是,它不会触发屏幕布局刷新。

我该如何解决这个问题?

【问题讨论】:

  • flag 不是状态,在效果内说flag = true 什么都不做。
  • 每次渲染组件时都会初始化flag 变量。如果你想坚持它的价值。为它创建一个状态。
  • 我已经改成状态变量了,问题依旧存在。
  • 不是根据您显示的代码:如果您更改代码,会发生什么变化,这意味着您的问题会发生变化,因此请更新您的帖子。
  • 我已经更新了。

标签: javascript reactjs use-reducer


【解决方案1】:

你实际上想做什么?这是非常不清楚的。您看到它在控制台中登录两次的原因是因为您有两次调用 undoUtil.set

    setTimeout(() => {
      temp["a"][0] = 75;
      undoUtil.set(temp);
    }, 0);

    setTimeout(
      ()=>{
        temp['a'][1]=20;
        undoUtil.set(temp);
      }
    ,0);

为什么是setTimeout?怎么回事?

我知道,不是答案,但评论太长了。

【讨论】:

  • 感谢您对我的问题的关注。经过多次试验,我发现setTimeout可以帮助解决问题。
  • @TheKNVB - 作为一般规则,如果您可以使用 setTimeout 修复某些问题,那么您很可能只会让事情变得更糟。
【解决方案2】:

最后,我在DEF.js 中发现了问题。可能是下面的代码导致了这个问题。

  temp["a"][0] = 75;
  undoUtil.set(temp);
  temp['a'][1]=20;
  undoUtil.set(temp);

所有的undoUtil.set 都在使用同一个变量temp,可能有些东西被覆盖了。

除此之外,useUndoUtil.js 中的 set 方法可能有同样的问题,

    case "set":
        console.log("before:"+JSON.stringify(state.presentValue));
        let temp=JSON.parse(JSON.stringify(state.pastValue));
        temp.push(JSON.parse(JSON.stringify(state.presentValue)));
        state.pastValue=temp;
        state.presentValue=JSON.parse(JSON.stringify(action.value));
        console.log("after:"+JSON.stringify(state.presentValue));
        return state;
        break;

在我将DEF.js中的代码更改为如下:

temp['a'][0]=75;    
undoUtil.set(JSON.parse(JSON.stringify(temp)));
temp['a'][1]=20;
undoUtil.set(JSON.parse(JSON.stringify(temp)));

useUndoUtil.js 中的代码如下:

case "set":
    let temp=JSON.parse(JSON.stringify(state.pastValue));
    temp.push(JSON.parse(JSON.stringify(state.presentValue)));
    return {
      pastValue:temp,
      presentValue:JSON.parse(JSON.stringify(action.value))
    }
    break;

它似乎按我的预期工作。谢谢你,亚当,如果没有人关心这个问题, 我不会重试解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2023-03-31
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    相关资源
    最近更新 更多