React + useState()+ previousState

Sep 11 2020

私は反応するのがまったく新しいので、useStateフック、より具体的にはpreviousStateの側面を理解するのに問題があります。

通常のuseStateフック、そしておそらく最も一般的な例は、次のようになります。

import React, { useState} from 'react';

export default function CounterHooks({ initialCount }){
  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <button onClick={() => setCount(count -1)}>-</button>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

私がこれまでに理解していることは、次のとおりです。

  • useState()関数/フックを呼び出しますか?初期状態の引数(initialCount)を渡します
  • すぐに変数countとsetCount(関数)に分解する配列を取得します
  • setCount()を使用すると、状態を更新できるため、カウント変数を更新できます。

これまでのところ良いと思います...;)

時々私は私が理解していないprevState(prevCount)で同じ反例を見ます:

<button onClick={() => setCount(prevCount => prevCount -1)}>-</button>

ここでは何が起きるのですか?この部分はわかりません。これまでの私の考え:

  • この場合、どういうわけか前のカウント値にアクセスします。
  • setCountは関数を期待します
  • setCountが非同期で実行されるようになりました
  • この関数はどこから来ていますか?
  • prevCountはどこから来ていますか?
  • これを実行すると、prevCountに何が入りますか?

私の混乱を理解していますか?私はこれをどのように異なって組み立てるべきかわかりません...

ご助力ありがとうございます。

回答

6 devserkan Sep 11 2020 at 19:15

まず、公式説明はこちらからご覧いただけます。

この場合、どういうわけか前のカウント値にアクセスします。

どういうわけか前のカウント値にアクセスしていません。機能更新を使用してセッターにコールバック関数を与えると、以前の状態が返され、この値をコールバック関数で使用します。

setCountは関数を期待します

機能を提供しているので、それを使用できます。

setCountが非同期で実行されるようになりました

実は違う。非同期関数ではありません。以前の状態を提供するだけで、それを使用します。状態セッターは非同期ではなく、状態の更新は非同期です。

この関数はどこから来ていますか?

prevCountはどこから来ていますか?

すでに答えました。

これを実行すると、prevCountに何が入りますか?

そこに新しい状態を設定するために何を設定しますか。あなたの例では、count1ずつインクリメントしたいので、+ 1

これは、このロジックの素朴な説明です。ただのナイーブなもの。コールバックロジックを例示するためにこれを追加しています。これはReactとは関係ありません。setState.

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    return val(state);
  }

  return val;
}

const stateWithFunctionalUpdate = setState(prev => prev + 1);
const stateWithNormalUpdate = setState(9);
console.log(stateWithFunctionalUpdate);
console.log(stateWithNormalUpdate);

この例は、Reactの状態設定ロジックを模倣するのに適しているかもしれません。繰り返しますが、単純なアプローチです。

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    state = val(state);
  } else {
    state = val;
  }

}

setState(9);
setState(prev => prev + 1);

console.log("state", state);

(入力なしで)の実際の実装を見てみましょうuseState:

export function useState(initialState) {
  return useReducer(
    basicStateReducer,
    // useReducer has a special case to support lazy useState initializers
    initialState
  );
}

まあ、それuseReducerはカーテンの後ろで使うだけです。初期状態を設定し、次のbasicStateReducerを使用します。

function basicStateReducer(state, action) {
  return typeof action === "function" ? action(state) : action;
}

私たちの素朴なアプローチのように、それはのタイプを探し、それにaction応じて動作します。最後に、これがuseReducer 返されるものです:

return [workInProgressHook.memoizedState, dispatch];

したがって、1日の終わりに、に関数を提供するとuseState、それを取得して状態で実行し、値を返します。

1 VietDinh Sep 11 2020 at 19:10

これが私の理解の仕方です:

この場合、どういうわけか前のカウント値にアクセスします。-> setCountはparamをチェックします。paramがコールバックの場合、そのコールバックを呼び出し、paramの前の状態を渡します。コールバックの結果は次の状態になります。

setCountは、関数を期待します->はい、関数はロジックを処理し、次の状態を返します。

setCountは非同期で実行されるようになりました->この関数は同期ですが、その後は結果を返します。setCountのフックは、次の状態を更新するためにイベントをディスパッチします

この関数はどこから来ていますか?-> paramが現在の状態であり、次の状態を返す限り、関数内で何でもできます。

prevCountはどこから来ていますか?-> setCountを呼び出すと渡されます(現在の状態から取得します)。

これを実行すると、prevCountに何が入りますか?-> setCountの現在の状態。

=>ここでsetCountに値またはコールバックを渡す方法の例:useStateフック、setState関数。以前の状態値へのアクセス