React Hooks-useStateと単なる変数の使用


12

React HooksはuseStateオプションを提供し、私は常にHooksとClass-Stateの比較を見ます。しかし、フックといくつかの通常の変数はどうですか?

例えば、

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

私はフックを使用しませんでした、そしてそれは私と同じ結果をもたらすでしょう:

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

それで、違いは何ですか?その場合、フックの使用はさらに複雑になります...それで、なぜそれを使い始めるのですか?


2つの異なるものを比較しています。フック付きの2番目の関数には、データを更新する機能があります。最初のものは実際には何もしていません。あなたはそれを使ってそれを初期化したかもしれませlet a = 1; return <div>{a}</div>ん、そしてあなたは同じ結果を得るでしょう。
Yathi、

回答:


13

その理由はuseState、ビューを再レンダリングする場合です。変数自体はメモリ内のビットを変更するだけであり、アプリの状態はビューと同期しなくなる可能性があります。

この例を比較してください:

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

どちらの場合もaクリックで変更されますがuseState、ビューを使用する場合にのみ、aの現在の値が正しく表示されます。


ありがとう!したがって、ビューをレンダリングする必要がない場合-データ(プロパティ)を配列に編成する方法のみ-'let'を使用できますか?私にとってはその作品、私はその大丈夫で許容できるものを知りたいだけです。
Moshe Nagar

@MosheNagarプロップからデータを取得する場合、コンポーネントはプロップの変更時に再レンダリングされるため、ビューがデータと同期するため、データを状態に保持する代わりにローカル変数を使用することをお勧めします。それらを状態に置いても、不必要な再レンダリングのみが発生します。最初にプロップが変更され、次に状態が変更されます。
marzelin

この回答を見てのもう一つの方法は、変数は第二の場合にはそれを考えることですa、それは実行を終了した後の最初の1で、それが活用以来ながらゴミは、収集されuseState、それはの価値保持されますa
ジョアン・マルコス・グリを

useRefビューを再レンダリングしたくない場合は、引き続き使用できます。ローカル変数またはReact参照を使用する必要があるかどうかという疑問が残ります。たとえば、クリアする必要のあるタイムアウト、またはaxiosを使用した継続中のhttpリクエストがある場合、タイムアウトまたはaxiosソースを変数またはReact refに保存しますか?
トム

3
@Tom原則として、派生状態にはローカル変数を使用します。それ以外の場合はuseRef(再レンダリングが不要なuseState場合)または(再レンダリングが必要な場合)を使用します。タイマーの場合、それらは副作用であるため、useEffectフックで開始する必要があります。あなたがしたい場合はtimerId、クリーンアップのためだけに、あなたはそれを保つことができるハンドラのローカル変数。コンポーネントの他の場所からタイマーをクリアできるようにするには、を使用する必要がありますuseRef。ローカル変数はレンダリングごとに「リセット」されるためtimerIdコンポーネントのローカル変数に格納するのは誤りです。
marzelin

1

状態を更新すると、コンポーネントは再び再レンダリングされますが、ローカル値はそうではありません。

あなたの場合、あなたはあなたのコンポーネントでその値をレンダリングしました。つまり、値が変更された場合、コンポーネントを再レンダリングして、更新された値を表示する必要があります。

したがってuseState、通常のローカル値よりも使用する方が良いでしょう。

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

最初の例が機能するのは、データが本質的に変更されないためです。使用の開始点はsetState、状態がハングしたときにコンポーネント全体を再レンダリングすることです。したがって、例で何らかの状態の変更または管理が必要な場合、変更値が必要であることをすぐに認識し、変数値でビューを更新するには、状態と再レンダリングが必要になります。


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

に相当

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

どのようなuseState二つのものが戻って、次のとおりです。

  1. 新しい状態変数
  2. その変数のセッター

呼び出すsetA(1)場合は、呼び出しthis.setState({ a: 1 })て再レンダリングをトリガーします。


0

ローカル変数は、状態が更新されるのに対し、変異時にレンダリングごとにリセットされます。

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

serene-galileo-ml3f0を編集

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.