Как реализовать shouldComponentUpdate в React
Что проверяют
Понимаете ли вы, когда React перерисовывает компонент и как остановить этот процесс вручную. Следом почти всегда спрашивают, чем заменить метод в функциональных компонентах и почему ручная оптимизация бывает вредна.
Как отвечать
shouldComponentUpdate(nextProps, nextState) есть только у классовых компонентов. React вызывает его перед повторным рендером, и если метод вернул false, пропускаются render и componentDidUpdate. При первом монтировании и при forceUpdate() он не вызывается.
Реализация сводится к сравнению this.props и this.state со следующими значениями. Сравнивать нужно всё, от чего зависит разметка, иначе интерфейс застрянет в старом состоянии. Поэтому чаще берут готовые варианты:
React.PureComponent: делает поверхностное сравнение пропсов и состояния за вас;React.memo(Component, arePropsEqual): аналог для функциональных компонентов. Логика второго аргумента обратная:trueозначает «пропсы равны, рендер не нужен»;useMemoиuseCallback: держат стабильные ссылки на объекты и функции, без них поверхностное сравнение каждый раз видит новые пропсы;- React Compiler: расставляет мемоизацию автоматически при сборке, и в новых проектах ручной
memoнужен всё реже.
Важная оговорка из документации: метод считается подсказкой для оптимизации, а не гарантией. false не остановит перерисовку дочерних компонентов, у которых поменялось собственное состояние или контекст, на который они подписаны.
Закончите тем, что оптимизация начинается с замера: React DevTools Profiler показывает, какие компоненты рендерятся лишний раз и сколько это стоит.
Где спотыкаются
Сравнивают один проп, как в учебном примере, и забывают про остальные пропсы и nextState. Компонент перестаёт реагировать на смену обработчика или состояния, и такой баг ищут долго.
Мутируют массивы и объекты вместо создания новых. Ссылка остаётся прежней, сравнение говорит «ничего не поменялось», и обновление теряется.
Делают глубокое сравнение через JSON.stringify или рекурсивный обход. На больших данных это дороже самого рендера, и оптимизация замедляет приложение.