我试图将一个值增加 1。无论我尝试什么,它都会增加超过 1。我知道该函数只会调用一次,并且仅在单击按钮时调用
const [counter, setCounter] = useState(0)
const handleSubmit = () => {
setCounter(counter + 1)
console.log('handleSubmit is running', counter) //TO SHOW ME HOW MANY TIMES THE FUNCTION RUNS. ONLY INCREMENTS BY 1 EACH TIME I CLICK THE BUTTON
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;
});
}