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