Как правильно предотвратить повторное рождение ребенка при изменении значения? - PullRequest
0 голосов
/ 07 апреля 2020

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

Как правильно хранить эти значения и обрабатывать изменения в состоянии без необходимости перерисовывать все дочерние элементы? Я хотел бы перерисовать только тот, который изменился.

Для текстовых полей я знаю, что есть другие альтернативы, но я использую только в качестве примера перерисовки. В моем реальном случае у меня есть другой компонент (кнопка переключения).

Я создал CodeSandbox, чтобы поделиться этим поведением:
https://codesandbox.io/s/blissful-black-lnvhh

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

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

В вашем случае вы определяете changed() в <App> при каждом повторном отображении компонента App и функции, переданной в FormContent, это не одно и то же.

const App = () => {
  const changed = values => {
    console.log(values);
  };

  return (
    <div className="App">
      <FormContent onChange={changed} />
    </div>
  );
};

Чтобы избежать этого, вы можете извлечь определение changed() и поместить его выше объявления компонента :

const changed = values => {
  console.log(values);
};

const App = () => {
  return (
    <div className="App">
      <FormContent onChange={changed} />
    </div>
  );
};

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

const changed = useCallback(() => { return (values) => console.log(values) }, []);

Он был создан для решения этой проблемы. [] в конце - массив зависимостей, и он ведет себя так же, как в useEffect().

useCallback

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

https://reactjs.org/docs/hooks-reference.html#usecallback

0 голосов
/ 07 апреля 2020

PureComponent

Используйте API-компонент Pure. Это будет только повторный рендеринг, если его реквизиты действительно изменится

class MyComponent extends React.PureComponent {

с документов

React.PureComponent аналогично React.Component. Разница между ними заключается в том, что React.Component не реализует shouldComponentUpdate (), а React.PureComponent реализует его с мелким сравнением состояния и поддержки.

Заметка

Если ваш компонент является функциональным компонентом, который вы можете использовать React.memo

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

Из документов

React.memo является компонентом более высокого порядка. Это похоже на React.PureComponent, но для компонентов функций вместо классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...