Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Рендеринг в React.js: Полный механизм
Что такое рендеринг
Рендеринг — это процесс преобразования компонентов React в реальные элементы DOM, которые видит пользователь. React использует сложный механизм для оптимизации этого процесса.
Фазы рендеринга
1. Фаза рендера (Render Phase)
Реакт анализирует изменения и подготавливает обновления:
function MyComponent({ count }) {
console.log("Render phase"); // Вызывается каждый раз
return <div>{count}</div>;
}
// Эта функция вызывается, но изменения НЕ применены на DOM
Что происходит:
- React вызывает функцию компонента
- Получает новый Virtual DOM (JSX структура)
- Сравнивает с предыдущим Virtual DOM (reconciliation)
- Определяет, какие изменения нужны
2. Фаза коммита (Commit Phase)
Реакт применяет все изменения на реальный DOM:
function MyComponent({ count }) {
useLayoutEffect(() => {
console.log("Commit phase: DOM обновлён");
}, [count]);
return <div>{count}</div>;
}
Процесс Reconciliation (Согласование)
Reconciliation — это алгоритм, который React использует для определения изменений:
// React сравнивает два дерева
const oldVDom = <div><span key="1">A</span></div>;
const newVDom = <div><span key="1">B</span></div>;
// Только текст изменится, структура остается
// React НЕ пересоздает элемент
Fiber архитектура
В React 16+ используется Fiber — улучшенный алгоритм рендеринга:
// Fiber разбивает большие обновления на части
// Это позволяет браузеру обрабатывать другие задачи
function HeavyComponent() {
const [items, setItems] = useState([]);
const handleClick = () => {
// React разделит это на небольшие chunks
setItems(Array(1000).fill(0).map((_, i) => i));
};
return (
<div>
<button onClick={handleClick}>Загрузить 1000 элементов</button>
{items.map(item => <div key={item}>{item}</div>)}
</div>
);
}
useState Батчинг (State Batching)
function Counter() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const handleClick = () => {
// React 18: оба setState вызываются в одном рендере
setCount(c => c + 1);
setText("clicked");
// Только ОДИН рендер вместо двух
};
return <button onClick={handleClick}>{count}</button>;
}
Асинхронный рендеринг (Concurrent Rendering)
React 18+ может прерывать рендеринг для более важных обновлений:
function SearchComponent() {
const [search, setSearch] = useState("");
const [results, setResults] = useState([]);
const handleChange = (e) => {
// Ввод текста (высокий приоритет)
setSearch(e.target.value);
// Результаты поиска (низкий приоритет)
startTransition(() => {
setResults(expensiveSearch(e.target.value));
});
};
return (
<input value={search} onChange={handleChange} />
);
}
useEffect и побочные эффекты
function MyComponent() {
// Рендер фаза (Render phase)
const [count, setCount] = useState(0);
console.log("Render:", count);
// Коммит фаза (Commit phase)
useLayoutEffect(() => {
console.log("LayoutEffect (синхронно)");
// Вызывается ДО отрисовки браузером
}, [count]);
useEffect(() => {
console.log("Effect (асинхронно)");
// Вызывается ПОСЛЕ отрисовки браузером
}, [count]);
return <div onClick={() => setCount(c => c + 1)}>{count}</div>;
}
// Порядок вывода:
// 1. Render: 0
// 2. LayoutEffect (синхронно)
// 3. Браузер отрисовывает DOM
// 4. Effect (асинхронно)
Оптимизация рендеринга
useMemo для дорогих вычислений
function ExpensiveComponent({ items }) {
const sortedItems = useMemo(
() => items.sort((a, b) => a - b),
[items]
);
return <div>{sortedItems.join(", ")}</div>;
}
useCallback для стабильных функций
function Parent() {
const handleClick = useCallback(() => {
console.log("Клик");
}, []); // Функция не пересоздается
return <Child onClick={handleClick} />;
}
React.memo для предотвращения ненужных рендеров
const MemoChild = React.memo(function Child({ data }) {
console.log("Child render");
return <div>{data}</div>;
});
function Parent() {
const [count, setCount] = useState(0);
return (
<>
<MemoChild data="static" />
<button onClick={() => setCount(c => c + 1)}>{count}</button>
</>
);
// MemoChild не перерисуется, так как data не изменилась
}
Ключи (Keys) в списках
// ❌ Плохо: используешь индекс как ключ
function List({ items }) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li> // Проблемы при сортировке
))}
</ul>
);
}
// ✅ Хорошо: уникальный идентификатор
function List({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
Итоги
Рендеринг в React состоит из:
- Render phase — подготовка изменений
- Commit phase — применение на DOM
- Fiber architecture — разбиение работы на chunks
- Reconciliation — умное сравнение Virtual DOM
- Concurrent rendering — приоритизация обновлений
Понимание этого механизма критично для написания производительного React кода.