在 React 中更新 State 对象中的嵌套属性
Update nested properties in a State object in React
在 React 中更新状态对象中的嵌套属性:
- 将函数传递
setState
给以访问当前状态对象。 - 使用扩展语法 (…) 创建对象和嵌套属性的浅表副本。
- 覆盖您需要更新的属性。
应用程序.js
import {useState} from 'react'; export default function App() { const initialState = { name: 'Alice', address: { country: 'Austria', coords: [1, 2], }, }; const [employee, setEmployee] = useState(initialState); const updateNestedProps = () => { setEmployee(current => { // 👇️ using spread syntax (...) return { ...current, address: { ...current.address, // 👇️ override value for nested country property country: 'Germany', }, }; }); }; return ( <div> <button onClick={updateNestedProps}>Click</button> <h4>{JSON.stringify(employee, null, 4)}</h4> </div> ); }
我们使用
扩展语法 (…)
将对象的键值对解压缩到一个新对象中,从而创建浅拷贝。
应用程序.js
const employee = { name: 'Alice', address: { country: 'Austria', coords: [1, 2], }, }; const newEmployee = { ...employee, address: { ...employee.address, // 👇️ override country property country: 'Germany', }, }; // 👇️ newEmployee.address.country is 'Germany' now console.log(newEmployee);
请注意,我们没有以任何方式直接改变状态对象。
We are unpacking the key-value pairs of the state object into a new object and overriding the properties we want to update.
The country
property overrides the property with the same name that exists on
the object because we provided it after using the spread syntax.
We passed a function to setState
, because the function is guaranteed to be
invoked with the current (most up to date) state.
App.js
const updateNestedProps = () => { setEmployee(current => { // 👇️ using spread syntax (...) return { ...current, address: { ...current.address, // 👇️ override value for nested country property country: 'Germany', }, }; }); };
When the next state is computed using the previous state, pass a function to
setState
.
Otherwise, we might get some weird race condition if the state object we have access to does not represent the most up to date value.
Alternatively, you can create a copy of the nested object and directly update
the property on the copy.
App.js
import {useState} from 'react'; export default function App() { const initialState = { name: 'Alice', address: { country: 'Austria', coords: [1, 2], }, }; const [employee, setEmployee] = useState(initialState); const updateNestedProps = () => { setEmployee(current => { // 👇️ get copy of nested object const address = {...current.address}; address.country = 'Germany'; return {...current, address}; }); }; return ( <div> <button onClick={updateNestedProps}>Click</button> <h4>{JSON.stringify(employee, null, 4)}</h4> </div> ); }
此示例实现了相同的结果,但更难阅读且更棘手。
我们创建了state.address
对象的副本并直接更新了
country
副本上的属性。
然后我们将address
新状态对象中的属性设置为我们更新的副本。
您选择哪种方法是个人喜好的问题。我会选择第一个示例,因为简单地覆盖我们想要更新的属性会更加直观。