Skip to main content

Рішення про перерисовку компонента

Коротка відповідь

React перерисовує компонент (re-render), коли:

  1. Змінюється його стан (state)
  2. Змінюються його властивості (props)
  3. Змінюється контекст (context), якщо він використовується в компоненті
  4. Його батько був перерендерений, і передав йому нові props (або навіть ті самі, але без оптимізації)

1. Зміна state

Якщо в компоненті викликається setState (або setCount, setUser тощо), React запускає повторний рендер цього компонента.

javascript
function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> {count} </button> ); }

Кожен виклик setCount() -> React створює нове Virtual DOM дерево для цього компонента і порівнює його з попереднім (diffing).


2. Зміна props

Якщо батьківський компонент передає нові props, React перерендерює дочірній компонент, щоб відобразити оновлені дані.

javascript
function Greeting({ name }) { return <h1>Привіт, {name}!</h1>; } function App() { const [name, setName] = useState("Alex"); return <Greeting name={name} />; }

Коли setName("Maria") -> React перерендерить App, а потім і Greeting, тому що його props.name змінилися.


3. Зміна контексту (useContext)

Якщо компонент підписаний на контекст через useContext, він перерисується при зміні значення контексту.

javascript
const ThemeContext = createContext("light"); function Button() { const theme = useContext(ThemeContext); return <button className={theme}>Click</button>; } function App() { const [theme, setTheme] = useState("light"); return ( <ThemeContext.Provider value={theme}> <Button /> </ThemeContext.Provider> ); }

setTheme("dark") -> усі компоненти, що використовують цей контекст, перерисуються.


4. Коли батько перерендерився

Навіть якщо props не змінилися за значенням, React все одно типово перерендерить дочірній компонент, якщо батько був перерендерений.

javascript
function Child() { console.log("Child render"); return <p>Дитина</p>; } function Parent() { const [count, setCount] = useState(0); return ( <> <button onClick={() => setCount(count + 1)}>+</button> <Child /> </> ); }

Кожен клік -> Parent оновлюється -> Child теж перерендериться, хоча в нього немає ні state, ні props.

Щоб цього уникнути, можна обгорнути Child в:

javascript
export default React.memo(Child);

Тепер React буде ререндерити Child лише якщо змінилися його props.


Що не викликає ререндер

Зміна змінних поза state

javascript
let count = 0; function Counter() { count++; // React не знає про count - вона не з state }

Зміна об'єкта "повз" setState

javascript
state.user.name = "Maria"; // React це не відстежить

Пряма зміна DOM (document.querySelector) React керує своїм Virtual DOM - він не стежить за ручними змінами реального DOM.


Як React вирішує, що саме оновити

Після того як React вирішує, що компонент має бути перерендерений:

  1. Він знову викликає функцію компонента (щоб отримати новий JSX).
  2. Створює нове Virtual DOM-дерево.
  3. Порівнює його з попереднім (diffing).
  4. Змінює лише те, що реально змінилося в реальному DOM (reconciliation).

Оптимізація: коли не потрібно перерендерювати

Використовуй React.memo() для функціональних компонентів: перерендериться лише при зміні props.

Використовуй useMemo() і useCallback(), щоб не пересоздавати функції та обчислення даремно.

Передавай стабільні значення (id, name тощо), а не нові об'єкти/функції при кожному рендері.


Підсумок

ПричинаКомпонент перерендериться?
Змінився stateТак
Змінилися propsТак
Змінився контекстТак
Батько перерендеривсяТак (якщо не React.memo)
Змінилася змінна поза stateНі
Пряма зміна DOMНі

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.