React + useState()+ previousState
私は反応するのがまったく新しいので、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に何が入りますか?
私の混乱を理解していますか?私はこれをどのように異なって組み立てるべきかわかりません...
ご助力ありがとうございます。
回答
まず、公式説明はこちらからご覧いただけます。
この場合、どういうわけか前のカウント値にアクセスします。
どういうわけか前のカウント値にアクセスしていません。機能更新を使用してセッターにコールバック関数を与えると、以前の状態が返され、この値をコールバック関数で使用します。
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、それを取得して状態で実行し、値を返します。
これが私の理解の仕方です:
この場合、どういうわけか前のカウント値にアクセスします。-> setCountはparamをチェックします。paramがコールバックの場合、そのコールバックを呼び出し、paramの前の状態を渡します。コールバックの結果は次の状態になります。
setCountは、関数を期待します->はい、関数はロジックを処理し、次の状態を返します。
setCountは非同期で実行されるようになりました->この関数は同期ですが、その後は結果を返します。setCountのフックは、次の状態を更新するためにイベントをディスパッチします
この関数はどこから来ていますか?-> paramが現在の状態であり、次の状態を返す限り、関数内で何でもできます。
prevCountはどこから来ていますか?-> setCountを呼び出すと渡されます(現在の状態から取得します)。
これを実行すると、prevCountに何が入りますか?-> setCountの現在の状態。
=>ここでsetCountに値またはコールバックを渡す方法の例:useStateフック、setState関数。以前の状態値へのアクセス