如果在之前已经回答了这个问题(也是很长的帖子,但我试图尽我所能)<)。但是,我发现的答案并不能完全满足我的满足。
我想为我的项目使用新的惊人的反应钩。对于我到目前为止一直在做的事情,它一直很简单。
现在,我遇到了一个更复杂的例子,我不确定自己最好应对这个。
假设,我有更多复杂的对象(至少不是平坦)在我的状态中。
{
persons: [
{
id: 1,
name: 'Joe Doe',
age: 35,
country: 'Spain',
interests: [
{ id: 1, en: 'Football', es: 'Fútbol' },
{ id: 2, en: 'Travelling', es: 'Viajar' }
]
},
{
id: 2,
name: 'Foo Bar',
age: 28,
country: 'Spain',
interests: [
{ id: 3, en: 'Computers', es: 'Computadoras' },
{ id: 4, en: 'Cooking', es: 'Cocinar' }
]
}
],
amount: 2,
foo: 'bar'
}
最好的方法是:
- 在我的同事数组中添加一个项目(对象)
- 将项目添加到特定的"兴趣"数组?
- 操纵数组中对象中属性的价值?
- 在人数数组之外更改一个值,例如
foo
?
使用usestate钩?
以下代码示例将尝试说明每个问题。他们没有经过测试...
让我们考虑我有一个从此开始的容器。它还包括在帖子其余部分中分配的功能。
const [colleagues, setColleagues] = useState({});
// using the useEffect as "componentDidMount
useEffect(() => {
// receiving data from ajax request
// and set the state as the example object provided earlier
setColleagues(response.data);
}, []);
1)因此对于第一个问题。这有效吗?还是我需要确保persons array
中的每个对象都会破坏?
const onAddNewColleague = () => {
// new colleague, this data would be dynamic
// but for the sake of this example I'll just hard code it
const newColleague = {
name: 'Foo Baz Bar',
age: 30,
country: 'Spain',
interests: [
{ en: 'Cats', es: 'Gatos' }
]
};
// creates a copy of the state
// targets the "persons" prop and adds a new array
// where the new colleague is appended
const newState = {
...colleagues,
persons: colleagues.concat(newColleague)
};
// updates the state
setColleagues(newState);
};
2)当我最终更新整个persons array
而不仅仅是特定人员的interest array
时,这感觉不错。
const onAddNewInterest = (personId) => {
// a new interest
const newInterest = {
en: 'Languages', es: 'Idiomas'
};
// find the person according to personId
// and update the interests
const updatedPersons = colleagues.persons.map(person => {
if(person.id === personId) {
return {
...person,
interests: person.interests.concat(newInterest);
};
}
return person;
});
// create a copy of the state
const newState = {
...colleagues,
persons: [...updatedPersons]
};
setColleagues(newState);
};
3)作为第二个示例,当我更新整个persons array
时,这也是错误的,而实际上我可能只想更改一个特定人员的age
const onChangeValue = (personId, key, value) => {
// find the person
const updatedPersons = colleagues.persons.map(person => {
if(person.id === personId) {
// key, could be age?
return {
...person,
[key]: value
};
}
return person;
});
// create a copy of the state
const newState = {
...colleagues,
persons: [...updatedPersons]
};
setColleagues(newState);
};
4)这是有效的,还是我需要分别破坏colleagues object
的每个部分?
const onChangeOtherValue = (key, value) => {
// for example changing the value foo
const newState = {
...colleagues,
[key]: value
};
setColleagues(newState);
};
我确实有一种感觉,只有第一个功能的概念是有效的,而其余的则没有。
可以轻松地做到这一点,还是我应该只使用不变的助手?
预先感谢!
更新的示例以获取语法,正确。谢谢valerii。
澄清我真正追求的是处理这样的用例的最佳练习。我想确保我的状态以最正确和有效的方式更新。因此,请随意撕开我的示例或写新的示例 - 我全都是耳朵。不必简单地修改我的文章(除非它们实际上是好的)。
1)OK
2)
const updatedPersons = colleagues.persons.map(person => {
if(person.id === personId) {
return {
...person,
interests: person.interests.concat({ en: 'Test', es: 'Test' })
};
}
return person;
});
const newState = {
...colleagues,
persons: updatedPersons
};
3)
const updatedPersons = colleagues.persons.map(person => {
if(person.id === personId) {
return {
...person,
[key]: value
};
}
return person;
});
// create a copy of the state
const newState = {
...colleagues,
persons: updatedPersons
};
4)OK
对于第一个,我会这样,
const newState = {
...colleagues,
persons: [...persons, newColleague]
};