大家下午好!
我有一个小问题,我有一个要添加到购物车的功能,单击时,我想将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,即使设置了该值也可能是什么?
谢谢你的关注,拥抱!
答案 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
时都会运行!它充当观察者。
在这里看到状态流吗? useEffect
到watch
对于状态更改有多方便?调试非常有用,您也应该这样使用!
最后,顺序很重要,因此当按下第二个CTA时,您会看到console.log(foobar)
的输出,该输出在内存中输出的值此时为two
,紧随其后的是{{ 1}}之所以执行更改,是因为它监视useEffect
,就像我所见过的第一个关于foobar
的情况一样。
[foobar]: One
对于这种特殊情况,当您调用 <button onClick={() => foobarHandler(setFoobar, foobar)}>click</button>
时,您将传递具有foobarHandler
的{{1}},并且在最后一次调用foobar
时是在外部范围内。在这种情况下(在foobarHandler内部),two
和three
没有耦合。
尝试创建useEffect并将foobar
添加为依赖项,然后运行console.log(changeFillCart),您会发现它发生了变化。