我是 React 的新手,我遇到了一个问题,我希望有人愿意帮助我理解为什么我的方法不起作用。
我有这个状态:
const [beers, setBeers] = useState([
{
id: 8759,
uid: "8c5f86a9-87bf-41fa-bc7f-044a9faf10be",
brand: "Budweiser",
name: "Westmalle Trappist Tripel",
style: "Fruit Beer",
hop: "Liberty",
yeast: "1056 - American Ale",
malts: "Special roast",
ibu: "22 IBU",
alcohol: "7.5%",
blg: "7.7°Blg",
bought: false
},
{
id: 3459,
uid: "7fa04e27-0b6b-4053-a26b-c0b1782d31c3",
brand: "Kirin",
name: "Hercules Double IPA",
style: "Amber Hybrid Beer",
hop: "Nugget",
yeast: "2000 - Budvar Lager",
malts: "Vienna",
ibu: "18 IBU",
alcohol: "9.4%",
blg: "7.5°Blg",
bought: true
}]
我正在使用 map 函数渲染啤酒,我有一些调用 handleClick 函数的 jsx
<button onClick={() => handleClick(beer.id)}>
{beer.bought ? "restock" : "buy"}
</button>
这是被调用的函数:
const handleClick = (id) => {
setBeers((currentBeers) =>
currentBeers.map((beer) => {
if (beer.id === id) {
beer.bought = !beer.bought;
console.log(beer);
}
return beer;
})
);
};
我想使用一个更新函数来更新状态,我直接在 setter 函数内部进行映射,因为 map 返回一个新数组,我认为一切都会正常工作,但事实并非如此。它仅在第一次单击按钮时起作用,之后它停止更新值。
我注意到如果我使用这个方法:
const handleClick = (id) => {
const newbeers = beers.map((beer) => {
if (beer.id === id) {
beer.bought = !beer.bought;
}
return beer;
});
setBeers(newbeers);
};
然后一切都按预期工作。
谁能帮我理解为什么我的第一种方法不起作用?
最佳答案
好的,我想我已经弄明白了。我的沙箱和你的沙箱之间的区别在于包含 <StrictMode>
在索引文件中。删除它可以解决问题,但不是正确的解决方案。所以我挖得更深一些。
我们都错过的是,在您的代码中,您修改了先前传入的状态对象。您应该创建一个新的啤酒对象,然后对其进行修改。所以这段代码有效(我希望):
setBeers((currentBeers) =>
currentBeers.map((currentBeer) => { // changed beer to currentBeer
const beer = {...currentBeer};
if (beer.id === id) {
beer.bought = !beer.bought;
}
return beer;
)
});
希望对您有所帮助。
关于reactjs - React setter 函数未按预期更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70549368/