Функциональные компоненты React изменяют состояние родительского элемента из дочернего элемента без отображения всех дочерних элементов

#javascript #reactjs #react-hooks

#javascript #reactjs #реагирующие хуки

Вопрос:

Изменение состояния родительского компонента из дочернего с помощью перехватов в React может быть выполнено (как описано в нескольких местах, например, здесь и здесь ) с использованием совместного обратного вызова от родительского компонента к дочернему:

 function Parent() {
    const [value, setValue] = React.useState("");

    function handleChange(newValue) {
      setValue(newValue);
    }

    // Pass a callback to Child
    return <Child value={value} onChange={handleChange} />;
}
 

И затем вы можете использовать обратный вызов в дочернем элементе:

 function Child(props) {
    function handleChange(event) {
        props.onChange(event.target.value);
    }
  
    return <input value={props.value} onChange={handleChange} />
}
 

Недостатком этого подхода является то, что у вас несколько дочерних элементов. Обратный вызов должен быть передан в качестве аргумента всем дочерним элементам, и поскольку для обратного вызова требуется доступ к setValue, он должен быть объявлен внутри родительской функции.

Таким образом, функция обратного вызова будет создаваться при каждом отображении родительского элемента, и это заставит отображать всех дочерних элементов.

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

Комментарии:

1. Существует несколько случаев, когда вам может понадобиться состояние в родительском элементе. Например: reactjs.org/tutorial/tutorial.html#lifting-state-up

2. Приведенный пример является общим. Это не конкретный случай, это просто отражает общую проблему. Если вы проверите пример, приведенный в моем последнем комментарии, вы увидите ту же проблему, даже с предлагаемыми вами изменениями.

Ответ №1:

Это именно то, для чего был создан useCallback!

useCallback вернет сохраненную версию обратного вызова, которая изменяется только в том случае, если изменилась одна из зависимостей. Это полезно при передаче обратных вызовов оптимизированным дочерним компонентам, которые полагаются на равенство ссылок, чтобы предотвратить ненужное отображение

Вы можете изменить свой родительский компонент, чтобы он выглядел как:

 function Parent() {
    const [value, setValue] = React.useState("");

    const handleChange = React.useCallback((newValue) => {
       setValue(newValue);
    }, []);

    // Pass a callback to Child
    return <Child value={value} onChange={handleChange} />;
}