Как принудительно обновить компонент React

Введение

В этой статье мы покажем вам, как принудительно обновить компонент в React.js. В частности, мы дадим краткое введение в повторный рендеринг React, покажем, как принудительно обновлять компоненты на основе классов и как принудительно обновлять функциональные компоненты.

Реагировать на повторный рендеринг

В большинстве случаев React сам автоматически обрабатывает компоненты для повторного рендеринга. Причина этого может быть основана на том, когда реквизиты или состояние были обновлены. Таким образом, при изменении состояния или свойства компонент перерисовывается. Но что, если ваш компонент зависит от чего-то еще и не обязательно от вашего состояния или свойства? В этом случае вам может потребоваться принудительно обновить компонент, поскольку React может не обнаружить изменения.

Давайте посмотрим, как использовать это принудительное обновление для компонента React. Чтобы показать это, мы собираемся создать простое приложение для демонстрационных целей.

Внимание: Мы рассмотрим несколько концепций React, поэтому желательно иметь базовые знания о React.

Принудительное обновление компонентов на основе классов

Компонент класса имеет встроенный метод для повторного рендеринга компонента, который называется forceUpdate(), который используется для принудительного повторного рендеринга компонента. Вы можете подробнее прочитать о forceUpdate() метод на React Официальном сайте.

handleForceupdateMethod() {
    
    this.forceUpdate();
}

Внимание: Не рекомендуется полагаться на обновление компонентов с помощью forceUpdate() метод. Когда вы обнаружите, что вам нужен этот метод, вы должны сначала попытаться проанализировать свой код и выяснить, есть ли другая причина, по которой React не обновляет компонент. Вы можете обнаружить, что это вызвано ошибкой, или что вы можете реструктурировать свой код таким образом, чтобы позволить React правильно повторно отображать компонент самостоятельно.

Вот пример принудительного обновления компонента на основе классов:

import React from 'react'

class App extends React.Component {
    constructor() {
        super();
        this.handleForceupdateMethod = this.handleForceupdateMethod.bind(this);
    };

    handleForceupdateMethod() {
        this.forceUpdate();
    };

    render() {
        return (
            <div>
                <h1>Hello StackAbuse</h1>
                <h3>Random Number: { Math.random() }</h3>
                <button onClick={this.handleForceupdateMethod}>
                    Force re-render
                </button>
            </div>
        );
    }
}

export default App

В этом методе происходит гораздо больше, чем может показаться. Например, вызов forceUpdate() также запускает методы жизненного цикла для дочерних компонентов. И, как мы знаем из React, он будет обновлять DOM только в том случае, если разметка действительно изменилась.

Вы можете получить доступ к живой код здесь.

Принудительное обновление функциональных компонентов

Функциональные компоненты не имеют встроенного метода для повторного рендеринга компонентов, как это делают их аналоги на основе классов. Это означает, что у нас нет forceUpdate() доступный нам метод. Однако помните, что в React компоненты обычно перерисовываются из-за изменения состояния или реквизита. Используя это, мы можем получить способы заставить upate.

Начиная с версии 16.8+, в React есть концепция, называемая хуками, которую можно использовать в функциональных компонентах для обновления состояния, выполнения побочных эффектов и т. д. Мы будем использовать эти хуки в наших интересах, чтобы заставить компонент повторно рендериться.

Вот несколько примеров принудительного обновления функционального компонента:

Посмотрите на график useReducer крючок

const [ignored, forceUpdate] = useReducer(x => x + 1, 0);

function handleClick() {
    forceUpdate();
}

Редюсер в React обычно используется, когда у вас есть сложная логика состояния и действия. Здесь мы используем его просто для запуска обновления путем обновления фиктивной переменной состояния, x. Состояние должно фактически измениться, чтобы инициировать обновление, поэтому оно увеличивается при каждом вызове.

Использовать useState крючок

import React, { useState } from "react";


function useForceUpdate() {
    let [value, setState] = useState(true);
    return () => setState(!value);
}

export default function App() {
    
    const handleForceupdateMethod = useForceUpdate();

    return (
        <div className="App">
            <h1>Hello StackAbuse </h1>
            <h3>Random Number: { Math.random() }</h3>

            {/*
                Clicking on the button will force to re-render like force update does
            */}
            <button onClick={handleForceupdateMethod}>Force re-render</button>
        </div>
    );
}

Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!

Идея этого типа принудительного обновления очень похожа на useReducer в этом мы постоянно обновляем состояние, чтобы вызвать изменение. Вместо увеличения счетчика, как в предыдущем методе, здесь мы просто переключаем логическое значение, чтобы оно обнулялось при каждом вызове.

Посмотрите на график useState и useCallback крючки

import React, { useState , useCallback} from "react";

export default function App() {
    const [, updateState] = useState();
    const handleForceupdateMethod = useCallback(() => updateState({}), []);

    
    console.log("Rendering...");

    return (
        <div className="App">
            <h1>Hello StackAbuse</h1>
            <h3>Random Number: { Math.random() }</h3>

            {/*
                Clicking on the button will force to re-render like force update does
            */}
            <button onClick={handleForceupdateMethod}>Force re-render</button>
        </div>
    );
}

Опять же, эта стратегия работает, изменяя состояние. В этом случае, хотя технически мы не меняем ценностное государства, мы Он отправив ему новый объект, который React считает новым, поскольку он не выполняет «глубокие» проверки на равенство для состояния.

Как видите, здесь есть несколько способов добиться одного и того же. Имейте в виду, что все это технически анти-паттерны, и их следует избегать, когда это возможно. Но если вы не можете решить основную проблему и вам нужно принудительно обновить компонент, то любой из показанных здесь методов должен работать.

Заключение

В этой статье мы увидели, как принудительно обновлять компоненты React. Мы также увидели, как этого можно добиться как в функциональных, так и в классовых компонентах. Хотя это не обязательно хорошая практика, полезно понять, как это работает, если нам нужно использовать это в особых случаях.

Отметка времени:

Больше от Стекабьюс