在 React 中设置状态有更简单的方法吗?
Is there an easier way to setting status in React?
我只是 React 的初学者,我一直在寻找一种更简单的方式来设置状态。
一个重要的注意事项是它位于功能组件内。
const [ personState, setPersonsState ] = useState({
persons: [
{ name : 'Max', age : 28 },
{ name : 'Manu', age : 29 },
{ name : 'Stephanie', age : 26 }
]
});
我知道这种方式通常是这样的,而且效果很好。
setPersonsState({
persons: [
{ name : 'Max', age : 28 },
{ name : 'Ati', age : 29 },
{ name : 'Stephanie', age : 26 }
]
但我觉得每次都手动输入很难,所以我试着让我的生活更轻松。
const newState = personState;
newState.persons[1].name = 'Ati';
setPersonsState(newState)
这没有用,我不知道为什么。
当我 console.log 它们出来时,它成功地改变了,但由于某种原因状态没有刷新,尽管我使用了 set 命令。
我还注意到 React 有一些奇怪的行为,当我使用这个 newState.persons[1].name = 'Ati';
命令时它也改变了 personState
变量。
所以 personState
和 newState
变量在控制台中看起来都是这样的。
{persons: Array(3)}
persons: Array(3)
0: {name: "Max", age: 28}
1: {name: "Ati", age: 29}
2: {name: "Stephanie", age: 26}
length: 3
__proto__: Array(0)
__proto__: Object
对于为什么这不起作用的任何帮助或解释,我将不胜感激。
在您的代码中,您试图直接修改状态。相反,您可以复制数组并在那里修改您需要的值。
在这种情况下,我会尝试使用 .map()
来更新状态,如下所示:
setPersonsState(prevState => ({
persons: personState.map(e => {
if (e.name === 'Manu') e.name = 'Ati';
return e;
}));
});
希望对您有所帮助!
当您执行此行时 const newState = personState;
您并没有将 personState 中的对象复制到 newState,而是引用了 personState 并使 newState 引用它。
当您对 newState 进行更改时,就像您在更改 personState 一样,因为这两个变量的引用是相同的。你直接改变一个状态对象,这在 React 中是禁忌的,因为它不符合生命周期,这就是你得到这种奇怪行为的原因。
如果要将对象内容复制到这个新变量中,需要做:
const newState = Object.assign({}, personState)
或使用 Spread 语法
const newState = { ...personState }
之后,您可以使用 setPersonState
设置状态
注意:如果你有嵌套的对象,上面给出的这些方法只会进行浅拷贝,这意味着只会复制第一层的值。
如果你想对对象进行深度复制,你要么必须进行多个对象传播(这是 redux 状态管理中的常见模式),例如
let state = {a: "val", b: { c: "val" }}
let newState = {
...state,
b: {
...state.b
}
}
或者使用 lodash 的 deepClone
例如
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
我只是 React 的初学者,我一直在寻找一种更简单的方式来设置状态。 一个重要的注意事项是它位于功能组件内。
const [ personState, setPersonsState ] = useState({
persons: [
{ name : 'Max', age : 28 },
{ name : 'Manu', age : 29 },
{ name : 'Stephanie', age : 26 }
]
});
我知道这种方式通常是这样的,而且效果很好。
setPersonsState({
persons: [
{ name : 'Max', age : 28 },
{ name : 'Ati', age : 29 },
{ name : 'Stephanie', age : 26 }
]
但我觉得每次都手动输入很难,所以我试着让我的生活更轻松。
const newState = personState;
newState.persons[1].name = 'Ati';
setPersonsState(newState)
这没有用,我不知道为什么。
当我 console.log 它们出来时,它成功地改变了,但由于某种原因状态没有刷新,尽管我使用了 set 命令。
我还注意到 React 有一些奇怪的行为,当我使用这个 newState.persons[1].name = 'Ati';
命令时它也改变了 personState
变量。
所以 personState
和 newState
变量在控制台中看起来都是这样的。
{persons: Array(3)}
persons: Array(3)
0: {name: "Max", age: 28}
1: {name: "Ati", age: 29}
2: {name: "Stephanie", age: 26}
length: 3
__proto__: Array(0)
__proto__: Object
对于为什么这不起作用的任何帮助或解释,我将不胜感激。
在您的代码中,您试图直接修改状态。相反,您可以复制数组并在那里修改您需要的值。
在这种情况下,我会尝试使用 .map()
来更新状态,如下所示:
setPersonsState(prevState => ({
persons: personState.map(e => {
if (e.name === 'Manu') e.name = 'Ati';
return e;
}));
});
希望对您有所帮助!
当您执行此行时 const newState = personState;
您并没有将 personState 中的对象复制到 newState,而是引用了 personState 并使 newState 引用它。
当您对 newState 进行更改时,就像您在更改 personState 一样,因为这两个变量的引用是相同的。你直接改变一个状态对象,这在 React 中是禁忌的,因为它不符合生命周期,这就是你得到这种奇怪行为的原因。
如果要将对象内容复制到这个新变量中,需要做:
const newState = Object.assign({}, personState)
或使用 Spread 语法
const newState = { ...personState }
之后,您可以使用 setPersonState
注意:如果你有嵌套的对象,上面给出的这些方法只会进行浅拷贝,这意味着只会复制第一层的值。
如果你想对对象进行深度复制,你要么必须进行多个对象传播(这是 redux 状态管理中的常见模式),例如
let state = {a: "val", b: { c: "val" }}
let newState = {
...state,
b: {
...state.b
}
}
或者使用 lodash 的 deepClone
例如
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);