如果在之前已经回答了这个问题,我会提前道歉(还有很长的帖子,但是我已经尽我所能了)。。但是,我找到的答案并不能完全让我满意。
我想在我的项目中使用新的惊人的React Hooks。到目前为止,我一直在做这件事。
现在我遇到了一个更复杂的示例,我不确定如何最好地解决这个问题。
比方说,我的状态中有更多的复杂对象(至少它不是平坦的)。
{
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。
要澄清 我真正想要的是处理此类用例的最佳实践。我想确保以最正确,最有效的方式更新我的状态。因此,请随意翻阅我的示例或撰写新示例-我全神贯注。不必简单地修改我的职位以适合该职位(除非他们实际上证明是好的)。
答案 0 :(得分:0)
1)好
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)好
答案 1 :(得分:0)
对于第一个,我会这样做,
const newState = {
...colleagues,
persons: [...persons, newColleague]
};