Como forçar a atualização de um componente React

Introdução

Neste artigo, mostraremos como forçar a atualização de um componente no React.js. Mais especificamente, faremos uma breve introdução às rerenderizações do React, mostraremos como forçar atualizações em componentes baseados em classe e como forçar atualizações em componentes funcionais.

Reagir Re-renderiza

O próprio React lida automaticamente com componentes de renderização para você, na maioria dos casos. A causa disso pode ser baseada em quando props ou state foram atualizados. Portanto, quando um estado ou propriedade muda, o componente é renderizado novamente. Mas e se o seu componente for dependente de outra coisa e não necessariamente do seu estado ou propriedade? Nesse caso, você pode precisar forçar a atualização do componente, pois o React pode não ter detectado a alteração.

Vamos dar uma olhada em como usar essa atualização forçada em um componente React. Para mostrar isso, vamos criar um aplicativo simples para fins de demonstração.

Note: Estaremos abordando alguns conceitos do React, portanto, é aconselhável ter conhecimento básico do React.

Forçando atualizações em componentes baseados em classe

O componente de classe tem um método embutido para renderizar novamente um componente, chamado forceUpdate(), que é usado para forçar um componente a renderizar novamente. Você pode ler mais sobre o forceUpdate() método no React's website oficial.

handleForceupdateMethod() {
    
    this.forceUpdate();
}

Note: Não é aconselhável confiar na atualização de componentes usando o forceUpdate() método. Quando você precisar desse método, você deve primeiro tentar analisar seu código e descobrir se há outra razão pela qual o React não está atualizando o componente. Você pode descobrir que um bug está causando isso ou que você pode reestruturar seu código de uma maneira que permita que o React re-renderize adequadamente o componente por conta própria.

Aqui está um exemplo de como forçar uma atualização em um componente baseado em classe:

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

Há muito mais acontecendo dentro deste método do que pode parecer. Por exemplo, chamando forceUpdate() também aciona os métodos de ciclo de vida para os componentes filhos. E como sabemos com o React, ele atualizará o DOM apenas se a marcação realmente tiver mudado.

Você pode acessar o código ao vivo aqui.

Forçando atualizações em componentes funcionais

Componentes funcionais não possuem um método embutido para re-renderizar um componente como suas contrapartes baseadas em classe fazem. Isso significa que não temos o forceUpdate() método disponível para nós. No entanto, lembre-se de que os componentes React normalmente são renderizados novamente devido a alterações de estado ou prop. Usando isso, podemos obter maneiras de forçar a atualização.

A partir da v16.8+, o React tem um conceito chamado Hooks que pode ser usado em componentes funcionais para atualizar o estado, realizar efeitos colaterais, etc. Usaremos esses hooks para nossa vantagem ao fazer um componente renderizar novamente.

Aqui estão alguns exemplos de como forçar uma atualização em um componente funcional:

Com o useReducer gancho

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

function handleClick() {
    forceUpdate();
}

Um redutor no React é normalmente usado quando você tem ações e lógicas de estado complexas. Aqui nós o usamos simplesmente para acionar a atualização atualizando uma variável de estado fictícia, x. O estado deve realmente mudar para acionar a atualização, e é por isso que é incrementado em cada chamada.

Use o useState gancho

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>
    );
}

Confira nosso guia prático e prático para aprender Git, com práticas recomendadas, padrões aceitos pelo setor e folha de dicas incluída. Pare de pesquisar comandos Git no Google e realmente aprender -lo!

A ideia por trás desse tipo de atualização de força é muito semelhante à useReducer em que estamos constantemente atualizando o estado para forçar a mudança. Em vez de incrementar um contador, como fizemos no último método, aqui simplesmente alternamos um valor booleano para que seja negado em cada chamada.

Com o useState e useCallback ganchos

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>
    );
}

Novamente, essa estratégia funciona mudando o estado. Nesse caso, embora não estejamos alterando tecnicamente o valor do estado, nós e guarante que os mesmos estão enviando a ele um novo objeto, que é considerado novo pelo React, pois não faz verificações de igualdade “profundas” no estado.

Como você pode ver, existem várias maneiras de conseguir a mesma coisa aqui. Tenha em mente que estes são todos tecnicamente antipadrões e devem ser evitados quando possível. Mas se você não conseguir resolver o problema subjacente e precisar forçar a atualização de um componente, qualquer um dos métodos que mostramos aqui deve funcionar.

Conclusão

Neste artigo vimos como forçar atualizações em componentes React. Também vimos como isso pode ser alcançado em componentes funcionais e baseados em classes. Embora não seja necessariamente uma boa prática, é útil entender como ela funciona caso precisemos usá-la em casos especiais.

Carimbo de hora:

Mais de Abuso de pilha