useState对象未正确更新



当我们尝试同时更新useState对象属性时。它没有更新。

const [stateData, setStatedata] = useState({
id: 0,
name: '',
address: '',
street: '',
city: '',
country: '',
property1: '',
property2: ''
etc...
});

当我尝试在文本更改事件上更新属性1时

const test = () => {
if(case == 1){
setStatedata({
...stateData,
property1: '123'
});
}
else{
// Do something
}
setStatedata({
...stateData,
property2: '654'
});
}

在这种情况下,属性1的值不会设置为123。

但它并不是在等待属性1的值更新。以前更新的值并不总是存在。

如果我需要20个或更多的状态属性,哪个是更好的解决方案?

  1. 对象
  2. 每个属性的单个状态

您应该以以下方式更新状态值:

setStatedata(state=> ({
...state,
property2: '65554'
}));

此外,您可以使用我的lib中的一个自定义钩子来实现深度状态管理器(Live Demo(:

import React from "react";
import { useAsyncDeepState } from "use-async-effect2";
function TestComponent(props) {
const [state, setState] = useAsyncDeepState({
x: 123,
y: 456
});
const incX = () => {
setState(({ x }) => ({ x: x + 1 }));
};
const incY = () => {
setState(({ y }) => ({ y: y + 1 }));
};
return (
<div className="component">
<div className="caption">useAsyncDeepState demo</div>
<div>state.x : {state.x}</div>
<div>state.y : {state.y}</div>
<button onClick={() => incX()}>Inc X</button>
<button onClick={() => incY()}>Inc Y</button>
</div>
);
}

如果在异步代码的上下文中使用,并且您需要等待实时演示的更新

import React, { useCallback, useEffect } from "react";
import { useAsyncDeepState } from "use-async-effect2";
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
function TestComponent(props) {
const [state, setState] = useAsyncDeepState({
counter: 0,
computedCounter: 0
});
useEffect(() => {
setState(({ counter }) => ({
computedCounter: counter * 2
}));
}, [state.counter]);
const inc = useCallback(() => {
(async () => {
await delay(1000);
await setState(({ counter }) => ({ counter: counter + 1 }));
console.log("computedCounter=", state.computedCounter);
})();
});
return (<button onClick={inc}>Inc</button>);
}

我尝试这个代码为我工作,你可以尝试这个:代码沙箱

const [stateData, setStatedata] = useState({
id: 0,
name: '',
address: '',
street: '',
city: '',
country: '',
property1: '',
property2: ''
});

const test = () => {
setStatedata({
...stateData,
property1: '123'
});

}
const test2 = () => {

setStatedata({
...stateData,
property2: '65554'
});
}
console.log(stateData)
return (
<div className="App">
<h1 onClick={() => test()}>Click Here</h1>
<hr />
<h1 onClick={() => test2()}>Click Here2</h1>
<h2></h2>
</div>
);

您应该通过两个参数的文本更改事件点击。

  1. 要在状态对象中更改的对象属性名称。例如:-属性1
  2. 要为该Object属性设置的值。例如:-任何值(文本事件值(

你的测试功能就像这个

const test = (key,value) => {
setStatedata({...stateData,[key]:value})
}

现在,您不需要创建多个函数来更改对象值。

最新更新