Перейти к основному содержимому

React Context не вызывает лишние рендеры

·243 слов·2 минут·
Александр Мунько
Автор
Александр Мунько
Любитель порассказывать про Фронтенд
Оригинальная статья

Очередная статья про React Context и объяснение того, как с ним работать верно для обработки состояния. Статья поясняет, что разработчики предпочитают стейт-менеджеры, например Redux или Zustand вместо того, чтобы разобраться с контекстами.

В базовом примере автор статьи использует контекст для передачи state и setState через контекст без каких либо мемоизаций, и уже в таком сценарии Реакт не делает лишние рендеры компонентов, которые не были затронуты изменением состояния:

const ValueContext = createContext();

const Provider = ({ children }) => {
  const [value, setValue] = useState(0);

  return (
    <ValueContext.Provider value={{ value, setValue }}>
      {children}
    </ValueContext.Provider>
  );
};

Использование такого контекста позволяет проверить корректность его работы – лишних рендеров не будет. Для примера можно собрать такую же структуру как и в статье:

На изобаражении представлена иерархия компонентов из React DevTools
Пример иерархии компонентов приложения с React.Context. Демо на CodePen

Для такого примера App и UncontrolledComponent не будут рендерится, т.к. не используют Context Consumer – триггер Update вызовет обновление состояния.

На изобаражении представлены компоненты, какие были затронуты триггером Update и какие не были затронуты
Компоненты, затронутые изменением React.Context

Автор считает, что путаница возникает из-за того, что в один контекст складывают все возможные состояния.

Совет по оптимизации

Если передавать дочерние элементы через пропы, например через {children}, то они не будут рендерится при изменении состояния компонента. Данный подход хорошо себя показывает вкупе с React.Context.

Всё это полезно для небольших и средних приложений, а для крупных уже лучше использовать стейт-менеджеры – их проще поддерживать и писать, и в большом приложении мы уже готовы заплатить весом бандла за улучшение DX.