Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як зменшити зайві рендери в React без memo: опустити стан нижче і передати JSX як children?

Коли змінюється стан компонента, React перерендерює його і всіх нащадків. Перш ніж обгортати все в memo, варто змінити структуру - часто цього досить.

1. Опустити стан туди, де він потрібен (state colocation):

// було: введення в пошук перерендерює всю сторінку
function Page() {
  const [query, setQuery] = useState('');
  return (
    <>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <Results query={query} />
      <HeavySidebar />      {/* рендериться на кожну літеру */}
    </>
  );
}

// стало: стан живе в компоненті, якому він потрібен
function Search() {
  const [query, setQuery] = useState('');
  return (
    <>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <Results query={query} />
    </>
  );
}

function Page() {
  return (
    <>
      <Search />
      <HeavySidebar />      {/* більше не залежить від введення */}
    </>
  );
}

2. Передати важкий вміст як children:

function Collapsible({ children }) {
  const [open, setOpen] = useState(false);
  return (
    <section>
      <button onClick={() => setOpen(!open)}>Розгорнути</button>
      {open && children}
    </section>
  );
}

<Collapsible>
  <HeavyChart />
</Collapsible>

Коли змінюється open, React перерендерює Collapsible, але children - це JSX, створений батьком, і він не змінився. HeavyChart не рендериться заново.

Інші принципи з документації React:

  • не оновлювати стан в ефектах без потреби - ланцюжки «ефект встановлює стан - рендер - ефект» множать рендери;
  • обчислювати похідні значення під час рендеру, а не зберігати копію в стані;
  • прибирати зайві залежності ефектів - функції й об'єкти, створені в тілі компонента, змінюються на кожен рендер.

Рендер - не обов'язково проблема. Рендер - це виклик функції й порівняння результату; DOM змінюється лише там, де результат відрізняється. Оптимізувати варто тоді, коли профілювання показує помітні затримки, а не «про всяк випадок».

React Compiler автоматично додає мемоізацію, але структурні рішення лишаються корисними: чим менше компонентів залежить від стану, що часто змінюється, тим менше роботи взагалі.

Докладніше в документації: memo: чи варто додавати memo всюди

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання