За кулисами React использует виртуальный DOM и процесс, называемый согласованием, для эффективного обновления фактического DOM и отображения пользовательских интерфейсов.
- Виртуальное представление DOM:
- Когда компонент React визуализируется, он возвращает представление виртуального DOM пользовательского интерфейса в виде дерева элементов React. Это упрощенное представление реального DOM в памяти.
пример:
const VirtualDom = () => { return ( <div> <h1>Hello, World!</h1> <p>This is a simple React component.</p> </div> ); };
2. Первоначальный рендеринг:
- Во время первоначального рендеринга React создает представление Virtual DOM и выполняет полный рендеринг дерева компонентов.
- React преобразует элементы Virtual DOM в настоящие узлы DOM и вставляет их в документ. Это первоначальный рендер пользовательского интерфейса.
ReactDOM.render(<VirtualDom />, document.getElementById('root'));
3. Состояние компонента и параметры:
- Компоненты React могут иметь состояние и свойства. Состояние представляет собой внутренние данные компонента, которые могут меняться со временем, а реквизиты — это свойства, передаваемые компоненту от его родителя.
- Когда состояние или свойства меняются, React запускает повторный рендеринг компонента.
const Counter = ({ initialValue }) => { const [count, setCount] = useState(initialValue); return ( <div> <h1>Count: {count}</h1> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); };
4. Сверка и расхождение:
- Перед обновлением фактического DOM React выполняет процесс, называемый согласованием.
- Во время согласования React сравнивает предыдущее представление Virtual DOM с новым, созданным обновленным состоянием или реквизитами.
- React определяет минимальный набор изменений, необходимых для обновления фактического DOM, чтобы он соответствовал новому виртуальному DOM.
const List = ({ items }) => { return ( <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); };
5. Эффективные обновления DOM:
- После согласования React обновляет фактический DOM с минимальным набором изменений. Он использует эффективные стратегии обновления DOM, чтобы свести к минимуму количество манипуляций с DOM.
- React обновляет только те части DOM, которые изменились, избегая ненужных обновлений и перекомпоновок, что повышает производительность.
const List = ({ items }) => { return ( <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); };
6. Методы жизненного цикла компонентов:
- В процессе повторного рендеринга React вызывает определенные методы жизненного цикла компонента, если они реализованы. Эти методы позволяют компонентам выполнять действия до или после рендеринга.
class MyComponent extends React.Component { componentDidMount() { console.log('Component has been mounted.'); } componentDidUpdate(prevProps, prevState) { console.log('Component has been updated.'); } componentWillUnmount() { console.log('Component is about to be unmounted.'); } render() { return ( <div> <h1>Hello, World!</h1> </div> ); } }
7. Обработка событий и обновление состояния:
- Когда пользователи взаимодействуют с пользовательским интерфейсом (например, нажимают кнопку), React обрабатывает события и запускает обновления состояния.
- Когда состояние обновляется, React инициирует повторную визуализацию затронутых компонентов, чтобы отразить изменения.
const Counter = () => { const [count, setCount] = useState(0); const handleIncrement = () => { setCount(count + 1); }; return ( <div> <h1>Count: {count}</h1> <button onClick={handleIncrement}>Increment</button> </div> ); };
8. Асинхронные обновления и пакетный рендеринг:
- React использует концепцию под названием «пакетный рендеринг» для выполнения нескольких обновлений в одном пакете, уменьшая количество повторных рендерингов и обновлений DOM.
- React также использует асинхронный рендеринг для планирования обновлений и обеспечения бесперебойной работы пользователей.
const Counter = () => { const [count, setCount] = useState(0); const handleIncrement = () => { // Asynchronous state update due to batching setCount((prevCount) => prevCount + 1); setCount((prevCount) => prevCount + 1); }; return ( <div> <h1>Count: {count}</h1> <button onClick={handleIncrement}>Increment</button> </div> ); };