【发布时间】:2022-01-01 14:03:59
【问题描述】:
我对 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
}]
我正在使用地图函数渲染啤酒,并且我有一些调用 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);
};
然后一切都按预期进行。
谁能帮我理解为什么我的第一种方法不起作用?
【问题讨论】:
-
我在上面的代码中创建了一个sandbox,因为这也让我感到困扰。它似乎对我来说工作正常。你能查一下吗?
-
我能想到您之前的代码无法正常工作的几个原因,但我必须先看看您如何呈现啤酒列表才能准确定位。但是 Stuart 提供的沙箱似乎运行良好。你做了什么不同的事情吗?
-
嗨@Doppio 谢谢你也调查这个,这里是链接:codesandbox.io/s/quirky-elion-4ke2v?file=/src/App.js
-
嗨@StuartNichols,我确实你的例子似乎有效,它看起来几乎和我在这里做的一样gr.pinterest.com/pin/708754060108151596。感谢您抽出宝贵时间发送沙盒链接!
-
我仍然无法解释为什么它不起作用,但我可以确定中断的部分是
beer.bought = !beer.bought; return beer;行。如果您将代码更改为return { ... beer, bought: !beer.bought },那么它可以工作。虽然我没有正确的解释,但我知道我们不应该更新/改变 Array.map 元素的值(所以 beer.bought = xxxxx 是不行的)
标签: reactjs react-hooks