Крючки и неизменное состояние - PullRequest
1 голос
/ 05 марта 2019

Я заранее извиняюсь, если на этот вопрос уже был дан ответ до (а также для длинного поста, но я старался быть настолько конкретным, насколько это возможно) .Но ответы, которые я нашел, не полностью удовлетворяют меня.

Я хочу использовать новые удивительные 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'
}

Какой лучший способ:

  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);
};

У меня есть ощущение, что концепция первой функции действительна, а остальные - нет.

Можно ли это сделать легко, или я должен просто использоватьнеизменный помощник?

Заранее спасибо!

Обновлены примеры, чтобы получить синтаксис, верно.Спасибо, Валерий.

Чтобы прояснить То, что мне действительно нужно, - это лучшая практика для обработки вариантов использования, подобных этому.Я хочу убедиться, что мое состояние обновляется самым правильным и эффективным способом.Так что не стесняйтесь копировать мои примеры или писать новые - я весь в ушах.Нет необходимости просто изменять мой, чтобы соответствовать этому посту (если они на самом деле не оказываются хорошими). ​​

1 Ответ

0 голосов
/ 05 марта 2019

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) ОК

...