Ganchos de reacción: uso de useState versus solo variables

12

React Hooks nos da la opción useState, y siempre veo las comparaciones Hooks vs Class-State. Pero, ¿qué pasa con los ganchos y algunas variables regulares?

Por ejemplo,

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

No utilicé Hooks, y me dará los mismos resultados que:

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

Entonces, ¿cuál es la diferencia? Usar ganchos aún más complejo para ese caso ... Entonces, ¿por qué empezar a usarlo?

Moshe Nagar
fuente
Sin embargo, estás comparando 2 cosas diferentes. La segunda función con ganchos tiene la capacidad de actualizar los datos. El primero no está haciendo realmente nada. Podría haberlo inicializado con let a = 1; return <div>{a}</div>y obtendrá el mismo resultado.
Yathi

Respuestas:

13

La razón es si useStatevuelve a mostrar la vista. Las variables por sí mismas solo cambian bits en la memoria y el estado de su aplicación puede desincronizarse con la vista.

Compara estos ejemplos:

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

En ambos casos, los acambios al hacer clic, pero solo cuando utiliza useStatela vista, muestra correctamente ael valor actual.

marzelin
fuente
¡Gracias! Entonces, si no necesito renderizar la vista, solo una forma de organizar mis datos (accesorios) en una matriz, ¿puedo usar 'let'? Funciona para mí, solo quiero saber que está bien y es aceptable.
Moshe Nagar
@MosheNagar si deriva sus datos de accesorios, se recomienda usar variables locales en lugar de mantener los datos en estado porque el componente se volverá a cambiar de apoyo de todos modos, por lo que la vista estará sincronizada con los datos. Ponerlos en estado solo causaría una retribución innecesaria: primero en el cambio de apoyo, luego en el cambio de estado.
marzelin
Una forma más de ver esta respuesta es pensar que en el segundo caso, la variable aserá recolección de basura después de que termine de ejecutarse, mientras que en la primera, ya que aprovecha useState, conservará el valor dea
João Marcos Gris
Todavía podría usarlo useRefsi no quisiera volver a representar la vista. La pregunta sigue siendo si debe usar variables locales o Reaccionar referencias. Por ejemplo, si tiene un tiempo de espera que necesita borrar, o una solicitud http en curso usando axios, ¿almacena el tiempo de espera o la fuente de axios en una variable o en una referencia de React?
Tom
3
@Tom La regla general es usar variables locales para el estado derivado. Para cualquier otra cosa, use useRef(si no desea volver a procesar) o useState(si desea volver a procesar). En el caso de los temporizadores, ya que son efectos secundarios, deben iniciarse en useEffectgancho. Si lo desea timerIdsolo para fines de limpieza, puede mantenerlo en la variable local del controlador . Si desea poder borrar el temporizador de otro lugar del componente, debe usarlo useRef. AlmacenamientotimerId en un la variable local de componente sería un error ya que los vars locales se "restablecen" en cada render.
marzelin
1

La actualización del estado hará que el componente se vuelva a representar de nuevo, pero los valores locales no lo son.

En tu caso, representaste ese valor en tu componente. Eso significa que, cuando se cambia el valor, el componente se debe volver a representar para mostrar el valor actualizado.

Por lo tanto, será mejor usar useStateque el 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>;
}
Diamante
fuente
0

Su primer ejemplo solo funciona porque los datos esencialmente nunca cambian. El punto de entrada del uso setStatees volver a entregar todo su componente cuando el estado se cuelga. Entonces, si su ejemplo requirió algún tipo de cambio de estado o gestión, se dará cuenta rápidamente de que será necesario cambiar los valores y para actualizar la vista con el valor de la variable, necesitará el estado y la representación.

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

es equivalente a

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

Lo que useStatedevuelve son dos cosas:

  1. nueva variable de estado
  2. setter para esa variable

si llama setA(1), llamaría this.setState({ a: 1 })y activaría una nueva representación.

schogges
fuente
0

Las variables locales se restablecerán en cada render tras la mutación, mientras que el estado se actualizará:

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

Drew Reese
fuente