Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Механизм перерендера в React
Перерендер — это процесс пересчёта виртуального DOM и синхронизации реального DOM. Разработчик не вызывает перерендер явно; вместо этого он срабатывает автоматически при определённых условиях.
Что запускает перерендер
В React компонент перерендится при:
- Изменение state — самая частая причина
- Изменение props — компонент получает новые значения
- Изменение контекста — значение Context изменилось
- Изменение parent — родительский компонент перерендился
Способ 1: Изменение state через useState
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1) // Запускает перерендер
}
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
)
}
Каждый раз при вызове setCount компонент перерендится с новым значением.
Способ 2: Изменение state через useReducer
Для сложной логики состояния используется useReducer:
import { useReducer } from 'react'
function counterReducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 }
case 'DECREMENT':
return { count: state.count - 1 }
default:
return state
}
}
export function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 })
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT') })}>+</button>
<button onClick={() => dispatch({ type: 'DECREMENT') })}>-</button>
</div>
)
}
Способ 3: Реактивность через props
Когда родитель изменяет props, дочерний компонент перерендится:
export function Parent() {
const [message, setMessage] = useState('Hello')
return (
<div>
<Child message={message} />
<button onClick={() => setMessage('World')}>Change</button>
</div>
)
}
export function Child({ message }) {
return <p>{message}</p>
}
Способ 4: Использование Context
Context позволяет избежать props drilling:
import { createContext, useContext, useState } from 'react'
const ThemeContext = createContext()
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
setTheme(theme === 'light' ? 'dark' : 'light')
}
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}
export function ThemedComponent() {
const { theme, toggleTheme } = useContext(ThemeContext)
return (
<div style={{ background: theme === 'light' ? 'white' : 'black' }}>
<p>Current theme: {theme}</p>
<button onClick={toggleTheme}>Toggle</button>
</div>
)
}
Оптимизация перерендера
REact предоставляет инструменты для оптимизации:
import { memo, useMemo, useCallback } from 'react'
const MemoChild = memo(({ count }) => {
console.log('Child rendered')
return <p>Count: {count}</p>
})
export function Parent() {
const [count, setCount] = useState(0)
const [name, setName] = useState('John')
const expensiveValue = useMemo(() => {
return count * 2
}, [count])
const handleClick = useCallback(() => {
setCount(count + 1)
}, [count])
return (
<div>
<MemoChild count={count} onClick={handleClick} />
<input value={name} onChange={e => setName(e.target.value)} />
</div>
)
}
Понимание Virtual DOM
React использует Virtual DOM для оптимизации:
- State изменяется —
setCount(count + 1) - Virtual DOM пересчитывается — React создаёт новое дерево
- Сравнение (Diffing) — React сравнивает старое и новое дерево
- Обновление реального DOM — обновляются только изменённые элементы
Этот процесс очень быстрый благодаря эффективному алгоритму сравнения.
Ключевые моменты
- Перерендер автоматический — разработчик только меняет state
- useState и useReducer — основные способы запуска перерендера
- Context — для глобального состояния
- Оптимизация — используй memo, useMemo, useCallback при необходимости
- Virtual DOM — React оптимизирует реальные обновления DOM
Понимание механизма перерендера критично для написания эффективных React приложений.