[解決済み] Reactはフック使用時に状態更新関数をバッチ処理しますか?
2023-02-13 01:03:06
質問
クラス部品について。
this.setState
はイベントハンドラ内であれば一括して呼び出します。しかし、状態がイベントハンドラの外側で更新された場合、どうなるでしょうか。
useState
フックを使用した場合はどうなるでしょうか?
function Component() {
const [a, setA] = useState('a');
const [b, setB] = useState('b');
function handleClick() {
Promise.resolve().then(() => {
setA('aa');
setB('bb');
});
}
return <button onClick={handleClick}>{a}-{b}</button>
}
レンダリングは
aa - bb
をすぐにレンダリングするのでしょうか?それとも
aa - b
となり、その後
aa - bb
?
どのように解決するのですか?
TL;DR - もし状態変化が非同期でトリガーされた場合(例えばプロミスでラップされた場合)、それらはバッチされません。
これを試すためにサンドボックスをセットアップしてみました。 https://codesandbox.io/s/402pn5l989
import React, { Fragment, useState } from 'react';
import ReactDOM from 'react-dom';
import './styles.css';
function Component() {
const [a, setA] = useState('a');
const [b, setB] = useState('b');
console.log('a', a);
console.log('b', b);
function handleClickWithPromise() {
Promise.resolve().then(() => {
setA('aa');
setB('bb');
});
}
function handleClickWithoutPromise() {
setA('aa');
setB('bb');
}
return (
<Fragment>
<button onClick={handleClickWithPromise}>
{a}-{b} with promise
</button>
<button onClick={handleClickWithoutPromise}>
{a}-{b} without promise
</button>
</Fragment>
);
}
function App() {
return <Component />;
}
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
2つのボタンを作成しました。1つは、あなたのコード例のようにプロミスでラップされた状態の変化をトリガーし、もう1つは状態の変化を直接トリガーします。
コンソールを見ると、"with promise" ボタンを押すと、まず
a aa
と表示され
b b
であれば
a aa
となり
b bb
.
ですから、答えはノーです。この場合、レンダリングされないのは
aa - bb
をすぐにレンダリングするのではなく、状態が変わるたびに新しいレンダリングが開始され、バッチ処理は行われません。
しかし、「約束なし」ボタンをクリックすると、コンソールには
a aa
と表示され
b bb
をすぐに使えるようにします。
つまりこの場合、Reactは状態の変更を一括して行い、両方合わせて1回のレンダリングを行います。
関連
-
[解決済み] Apolloクライアントでログアウトした後、ストアをリセットする
-
[解決済み] error 'document' is not defined : eslint / React
-
[解決済み] Next.jsでWebSocketを利用する
-
[解決済み] react jsでウィンドウを開くイベントを処理するにはどうすればよいですか?
-
[解決済み] React JSでは、状態を直接変異させない、setState() react/no-direct-mutation-stateを使用する。
-
[解決済み] componentDidUpdate'メソッドはいつ使用するのですか?
-
[解決済み] Reactルータを使ったプログラムによるナビゲーション
-
[解決済み] setStateを呼び出さずにReactコンポーネントを強制的に再レンダリングすることは可能ですか?
-
[解決済み] useEffect React Hook使用時の依存性欠如の警告を修正する方法
-
[解決済み] Reactでネストした状態のプロパティを更新する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Jestの `beforeEach` グローバルは何のためにあるのですか?
-
[解決済み] jest: テストスイートの実行に失敗しました。予期しないトークンのインポート
-
[解決済み] Webpack + Babelです。プリセット "es2015 "がディレクトリに相対して見つからなかった
-
[解決済み] sh: react-scripts: npm start の実行後にコマンドが見つからない。
-
[解決済み] ReactjsのEsLintの "react / jsx-props-no-spreading "エラーを無効化する。
-
[解決済み] React TypeScriptで作業しているときに、Jestが予期しないトークンに遭遇した
-
[解決済み] nginxでcertbotを使用する際の問題点
-
[解決済み] ReactJS で inst.render が関数でないエラーが発生する
-
[解決済み] eslint: no-case-declaration - case ブロックで予期しない字句の宣言があった。
-
[解決済み】react hooksで`setState`コールバックを使用する方法