React Hooks - usando useState vs apenas variáveis


12

React Hooks nos fornece a opção useState, e eu sempre vejo comparações Hooks vs Class-State. Mas e Hooks e algumas variáveis ​​regulares?

Por exemplo,

function Foo() {
    let a = 0;
    a = 1;
    return <div>{a}</div>;
}

Eu não usei Hooks, e ele me dará os mesmos resultados que:

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

Então, qual é a diferença? Usando Hooks ainda mais complexo para esse caso ... Então, por que começar a usá-lo?


Você está comparando duas coisas diferentes. A segunda função com ganchos tem a capacidade de atualizar os dados. O primeiro não está realmente fazendo nada. Você poderia apenas inicializá-lo let a = 1; return <div>{a}</div>e obterá o mesmo resultado.
Yathi

Respostas:


13

O motivo é se você useStaterenderiza novamente a exibição. As variáveis ​​por si só alteram os bits da memória e o estado do seu aplicativo pode ficar fora de sincronia com a exibição.

Compare estes exemplos:

function Foo() {
    const [a, setA] = useState(0);
    return <div onClick={() => setA(a + 1)}>{a}</div>;
}

function Foo() {
    let a = 0;
    return <div onClick={() => a + 1}>{a}</div>;
}

Nos dois casos, as aalterações são feitas no clique, mas somente quando você usa useStatea exibição corretamente mostra ao valor atual.


Obrigado! Portanto, se não precisar renderizar a exibição - apenas uma maneira de organizar meus dados (adereços) em alguma matriz - posso usar 'let'? Funciona para mim, eu só quero saber que está tudo bem e aceitável.
Moshe Nagar

@MosheNagar se você deriva seus dados de props, é recomendável usar variáveis ​​locais em vez de manter os dados em estado, porque o componente será renderizado novamente na alteração de props de qualquer maneira, para que a visualização esteja sincronizada com os dados. Colocá-los em estado só causaria repetições desnecessárias - primeiro na mudança de prop, depois na mudança de estado.
marzelin

Mais uma maneira de olhar para essa resposta é pensar que, no segundo caso, a variável aserá coletada como lixo após concluir a execução, enquanto no primeiro, uma vez que aproveita useState, preservará o valor dea
João Marcos Gris

Ele ainda poderia usar useRefse não quisesse renderizar novamente a exibição. A questão permanece se ele deve usar variáveis ​​locais ou referências a reagir. Por exemplo, se você tiver um tempo limite que precisa limpar ou uma solicitação http em andamento usando axios, você armazena a fonte de tempo limite ou axios em uma variável ou em uma ref React?
Tom

3
@ Tom A regra geral é usar vars locais para o estado derivado. Para qualquer outra coisa, use useRef(se você não quiser renderizar novamente) ou useState(se você quiser renderizar novamente). No caso de temporizadores, por serem efeitos colaterais, eles devem ser iniciados no useEffectgancho. Se você deseja timerIdapenas para fins de limpeza, pode mantê-lo na variável local do manipulador . Se você deseja limpar o cronômetro de outro local do componente, use-o useRef. Armazenar timerIdna variável local de um componente seria um erro, pois os vars locais são "redefinidos" em cada renderização.
marzelin

1

A atualização do estado fará com que o componente volte a renderizar novamente, mas os valores locais não.

No seu caso, você renderizou esse valor em seu componente. Isso significa que, quando o valor é alterado, o componente deve ser renderizado novamente para mostrar o valor atualizado.

Portanto, será melhor usar do useStateque o valor local normal.

function Foo() {
    let a = 0;
    a = 1; // there will be no re-render.
    return <div>{a}</div>;
}

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // re-render required
    return <div>{a}</div>;
}

0

Seu primeiro exemplo funciona apenas porque os dados basicamente nunca são alterados. O ponto de entrada do uso setStateé renderizar novamente todo o componente quando o estado travar. Portanto, se seu exemplo exigir algum tipo de alteração ou gerenciamento de estado, você perceberá rapidamente que os valores de alteração serão necessários e, para atualizar a visualização com o valor da variável, será necessário o estado e a nova renderização.


0
function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

é equivalente a

class Foo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            a: 0
        };
    }
    // ...
}

Quais useStateretornos são duas coisas:

  1. nova variável de estado
  2. setter para essa variável

se você ligar, setA(1)você ligaria this.setState({ a: 1 })e acionaria uma nova renderização.


0

As variáveis ​​locais serão redefinidas a cada renderização após a mutação, enquanto o estado será atualizado:

function App() {
  let a = 0; // reset to 0 on render/re-render
  const [b, setB] = useState(0);

  return (
    <div className="App">
      <div>
        {a}
        <button onClick={() => a++}>local variable a++</button>
      </div>
      <div>
        {b}
        <button onClick={() => setB(prevB => prevB + 1)}>
          state variable b++
        </button>
      </div>
    </div>
  );
}

Editar serene-galileo-ml3f0

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.