钩和不变的状态



如果在之前已经回答了这个问题(也是很长的帖子,但我试图尽我所能)<)。但是,我发现的答案并不能完全满足我的满足。

我想为我的项目使用新的惊人的反应钩。对于我到目前为止一直在做的事情,它一直很简单。

现在,我遇到了一个更复杂的例子,我不确定自己最好应对这个。

假设,我有更多复杂的对象(至少不是平坦)在我的状态中。

{
    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'
}

最好的方法是:

  1. 在我的同事数组中添加一个项目(对象)
  2. 将项目添加到特定的"兴趣"数组?
  3. 操纵数组中对象中属性的价值?
  4. 在人数数组之外更改一个值,例如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]
    };

相关内容

  • 没有找到相关文章

最新更新