我试图将一个值增加 1。无论我尝试什么,它总是会增加超过 1。我知道该函数只会被调用一次,并且只有在单击按钮时才会被调用。
const [counter, setCounter] = useState(0)
const handleSubmit = () => {
setCounter(counter + 1)
// TO SHOW ME HOW MANY TIMES THE FUNCTION RUNS.
// ONLY INCREMENTS BY 1 EACH TIME I CLICK THE BUTTON
console.log('handleSubmit is running', counter)
setLeveledChar(prevChar => {
let newChar = { ...prevChar }
// INCRIMENTS BY 1
newChar.char_level++
// SELECTED CLASS IS DIFFERENT DEPENDING ON WETHER OR NOT
// ISmULTICLASING IS TRUE.
// EITHER THE SELECTED MULTICLASS OR LEVELEDcHAR.PRIMARY_CLASS
// BY CLASS I MEAN LIKE A ROLE PLAYING CLASS BTW. NOT A PROGRAMMING CLASS
const leveledClass = isMulticlassing
? newChar.multiclass.find(x => x.name === selectedClass.name)
: newChar.primary_class
// INCRIMENTS BY 2
leveledClass++
return newChar
})
}
我尝试了
leveledClass.level = leveledClass.level + 1
和leveledClass.level += 1
,但它们都加了2。
handleSubmit
正在改变当前状态的值,并且这种突变是通过React.StrictMode
组件对某些生命周期方法和钩子回调的双重调用(在本例中为useState
状态更新器功能)暴露/显现的。第一个调用按您的预期更新状态,但第二个调用也会改变状态,因此这就是为什么您会看到值以两位数而不是一个数递增。
所有 React 状态更新都必须浅复制正在更新的所有状态、和嵌套状态属性。这通常是通过功能状态更新来实现的。
实现示例:
const handleSubmit = () => {
setCounter(counter => counter + 1);
setLeveledChar(prevChar => {
// shallow copy of current leveledChar state object reference
const newChar = { ...prevChar };
// non-mutative update
newChar.char_level += 1;
if (isMulticlassing) {
// Shallow copy array with map function
newChar.multiclass = newChar.multiclass.map(x => x.name === selectedClass.name
? { // <-- new object reference and shallow copy array element
...x,
primary_class: x.primary_class + 1
}
: x
);
} else {
// non-mutative update
newChar.primary_class += 1;
}
return newChar;
});
}