简体   繁体   English

setState 未设置 state

[英]setState not setting the state

Good afternoon everyone!大家下午好!

I have a little problem, I have a function to add to the cart and when clicking, I wanted to change the fill property to true and then fill as soon as the icon is clicked, but my setState is not setting!我有一个小问题,我有一个 function 要添加到购物车,单击时,我想将填充属性更改为 true,然后在单击图标后立即填充,但我的 setState 没有设置!

This is the function:这是 function:

  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],
  );

And that's her call:这就是她的电话:

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

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

</div>

The setChangeFillCart and changeFillCart are coming via the properties of a fetch and I map them. setChangeFillCart 和 changeFillCart 是通过 fetch 的属性来的,我是 map 它们。 That console.log of else always shows that the value is false, even after its set, what could it be? else 的那个console.log 总是显示该值为false,即使在它设置之后,它会是什么?

I thank you for your attention, hugs!谢谢你的关注,抱抱!

changeFillCart is a local variable. changeFillCart是一个局部变量。 It's probably defined with a const , and even if it's a let it's never going to change anyway.它可能是用const定义的,即使它是let它也永远不会改变。 setChangeFillCart does not attempt to change your local variables. setChangeFillCart不会尝试更改您的局部变量。 Putting a log statement where you did is only ever going to log out what changeFillCart was equal to when loggedToAddCart was created在您所做的地方放置一个日志语句只会注销changeFillCart在创建时loggedToAddCart的内容。

The purposes of setChangeFillCart is to tell react to rerender the component. setChangeFillCart的目的是告诉 react 重新渲染组件。 When that second render happens, a new local variable will be created which will get the new value.当第二次渲染发生时,将创建一个新的局部变量,该变量将获取新值。 This variable is visible to anything created on that second render, not to things created on the first render.此变量对在第二次渲染上创建的任何东西都是可见的,而不是对在第一次渲染上创建的东西可见。 So if you want to see the new value, put your log statement in the body of the component so you can see what value it's rerendering with.因此,如果您想查看新值,请将您的日志语句放在组件的主体中,这样您就可以看到它正在重新渲染的值。

Your setState should be setting actually, I'll demonstrate it in a few steps and how to debug your issue in a sane matter, to help you fix this issue and in future cases...您的 setState 应该实际设置,我将通过几个步骤演示它以及如何在理智的情况下调试您的问题,以帮助您解决此问题以及在未来的情况下......

Let's look at a practical example.让我们看一个实际的例子。 Start by looking at the following:首先查看以下内容:

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>
  );
}

Which outputs the following on load:在负载时输出以下内容:

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

If you click the first CTA:如果单击第一个 CTA:

[foobar]:  two 

and after, the second CTA, you get:在第二个 CTA 之后,您将获得:

two 
[foobar]:  third 

If you click the second CTA again, you get:如果再次单击第二个 CTA,您将获得:

third 

When the application first runs, the useEffect is executed and you get undefined .当应用程序第一次运行时, useEffect被执行并且你得到undefined Followed by [foobar]: One !跟着[foobar]: One

This happens because the foobar state is not assigned a value in the useState() on the first run (componentDidMount).发生这种情况是因为foobar state 在第一次运行 (componentDidMount) 时未在useState()中分配值。

You see the output [foobar]: One because of the useEffect that has the dependency foobar , which runs every time foobar is updated.您会看到 output [foobar]: One ,因为useEffect具有依赖项foobar ,它在每次更新foobar时运行。 It acts as a watcher.它充当观察者。

See the state flow here?在这里看到 state 流程? How handy the useEffect can be to watch for state changes? watch state 变化的useEffect有多方便? It's useful to debug and you should use as such too!它对调试很有用,你也应该这样使用!

Finally, the order matters, so when the second CTA is pressed you see the output of the console.log(foobar) that outputs the value in memory that at this time is two , followed immediately by the useEffect that executes changes because it watches foobar just like the first case I've exposed about [foobar]: One .最后,顺序很重要,所以当第二个 CTA 被按下时,你会看到console.log(foobar)的 output 输出 memory 中的值,此时是two ,然后是执行更改的useEffect因为它监视foobar就像我公开的第一个案例[foobar]: One一样。

  <button onClick={() => foobarHandler(setFoobar, foobar)}>click</button>

For this particular case, when you call foobarHandler , you are passing foobar that has two and in the last call three in the outer scope.对于这种特殊情况,当您调用foobarHandler时,您传递的foobar在外部 scope 中具有two和最后一个调用three In this context (inside the foobarHandler), the foobar and setFoobar are not coupled.在这种情况下(在 foobarHandler 内部), foobarsetFoobar没有耦合。

Try to create a useEffect and add changeFillCart as a dependency, and run a console.log(changeFillCart) and you'll see it changes.尝试创建一个 useEffect 并将changeFillCart添加为依赖项,然后运行 console.log(changeFillCart) 你会看到它发生了变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM