setState未设置状态

时间:2020-04-28 20:49:37

标签: javascript reactjs

大家下午好!

我有一个小问题,我有一个要添加到购物车的功能,单击时,我想将fill属性更改为true,然后在单击图标后立即填充,但是我的setState没有设置! / p>

这是功能:

  const loggedToAddCart = useCallback(
    (brandName, productId, setChangeFillCart, changeFillCart) => {
      if (!uid) {
        setMessageToast('Register to save photos and see prices');
        setOpenToast(true);
        setChangeFillCart(false);
        return;
      }
      if (cartIds.includes(productId)) {
        setChangeFillCart(false);
        deleteFromCart(brandName, productId);
      } else {
        setChangeFillCart(true);
        console.log(changeFillCart);

        addToCart(brandName, productId);
      }
    },
    [cartIds],
  );

那就是她的电话:

<div onClick={() => loggedToAddCart(brandName, productId, setChangeFillCart, changeFillCart)}>

 <Icon type="shoppingBag" size={24} strokeWidth={1} fill={cartIds.includes(productId) || changeFillCart} />

</div>

setChangeFillCart和changeFillCart通过获取的属性来传递,我将它们映射。 该console.log的else总是显示该值是false,即使设置了该值也可能是什么?

谢谢你的关注,拥抱!

2 个答案:

答案 0 :(得分:0)

changeFillCart是局部变量。它可能是用const定义的,即使它是let也永远不会改变。 setChangeFillCart不会尝试更改您的局部变量。将日志语句放在您做过的地方只会注销changeFillCart等于创建loggedToAddCart时的情况

setChangeFillCart的目的是告诉响应以重新呈现组件。当第二次渲染发生时,将创建一个新的局部变量,它将获取新值。此变量对在第二个渲染器上创建的任何内容均可见,而对第一个渲染器上创建的内容不可见。因此,如果要查看新值,请将log语句放在组件主体中,以便查看其重新呈现的值。

答案 1 :(得分:0)

您的setState应该实际上是在设置,我将在几个步骤中演示它,以及如何合理地调试问题,以帮助您解决此问题,并在以后的情况下...

让我们看一个实际的例子。首先查看以下内容:

export default function App() {
  const [foobar, setFoobar] = useState()

  useEffect(() => {
    setFoobar("One")
    console.log("[foobar]: ", foobar)
  }, [])

  useEffect(() => {
    console.log("[foobar]: ", foobar)
  }, [foobar])

  const foobarHandler = useCallback((setFoobar, foobar) => {
    setFoobar("third")
    console.log(foobar)
  })

  return (
    <div className="App">
      <button onClick={() => setFoobar("two")}>click</button>
      <button onClick={() => foobarHandler(setFoobar, foobar)}>click</button>
    </div>
  );
}

在加载时输出以下内容:

[foobar]:  
undefined
[foobar]:  
undefined
[foobar]:  One 

如果您单击第一个CTA:

[foobar]:  two 

然后是第二个CTA,您会得到:

two 
[foobar]:  third 

如果再次单击第二个CTA,则会得到:

third 

应用程序首次运行时,将执行useEffect,您将得到undefined。跟着[foobar]: One

之所以会这样,是因为在第一次运行(componentDidMount)时,foobar状态没有在useState()中分配值。

您看到输出[foobar]: One是因为useEffect具有依赖项foobar,该依赖项每次更新foobar时都会运行!它充当观察者。

在这里看到状态流吗? useEffectwatch对于状态更改有多方便?调试非常有用,您也应该这样使用!

最后,顺序很重要,因此当按下第二个CTA时,您会看到console.log(foobar)的输出,该输出在内存中输出的值此时为two,紧随其后的是{{ 1}}之所以执行更改,是因为它监视useEffect,就像我所见过的第一个关于foobar的情况一样。

[foobar]:  One

对于这种特殊情况,当您调用 <button onClick={() => foobarHandler(setFoobar, foobar)}>click</button> 时,您将传递具有foobarHandler的{​​{1}},并且在最后一次调用foobar时是在外部范围内。在这种情况下(在foobarHandler内部),twothree没有耦合。

尝试创建useEffect并将foobar添加为依赖项,然后运行console.log(changeFillCart),您会发现它发生了变化。