[解決済み】useState setメソッドが変更を即座に反映しない。
質問
フックを勉強しようとしているのですが
useState
メソッドで混乱しました。私は配列の形でステートに初期値を代入しています。のsetメソッドは
useState
は、スプレッドシンタックスを使用した場合と使用しない場合の両方で、私には機能しません。
別のPCでAPIを作り、それを呼び出して状態に設定したいデータを取ってきています。
以下は私のコードです。
<div id="root"></div>
<script type="text/babel" defer>
// import React, { useState, useEffect } from "react";
// import ReactDOM from "react-dom";
const { useState, useEffect } = React; // web-browser variant
const StateSelector = () => {
const initialValue = [
{
category: "",
photo: "",
description: "",
id: 0,
name: "",
rating: 0
}
];
const [movies, setMovies] = useState(initialValue);
useEffect(() => {
(async function() {
try {
// const response = await fetch("http://192.168.1.164:5000/movies/display");
// const json = await response.json();
// const result = json.data.result;
const result = [
{
category: "cat1",
description: "desc1",
id: "1546514491119",
name: "randomname2",
photo: null,
rating: "3"
},
{
category: "cat2",
description: "desc1",
id: "1546837819818",
name: "randomname1",
rating: "5"
}
];
console.log("result =", result);
setMovies(result);
console.log("movies =", movies);
} catch (e) {
console.error(e);
}
})();
}, []);
return <p>hello</p>;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<StateSelector />, rootElement);
</script>
<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
どちらも
setMovies(result)
また
setMovies(...result)
が動作します。
を期待しています。
result
変数に押し込まれます。
movies
の配列になります。
どのように解決するのですか?
を拡張して作成されたクラスコンポーネントのsetStateとよく似ています。
React.Component
または
React.PureComponent
で提供されるアップデータを用いて、状態の更新を行う。
useState
フックも非同期であり、すぐには反映されない。
また、ここでの主な問題は、非同期であることだけではなく、状態の値が現在のクロージャに基づいて関数で使用され、状態の更新が次の再レンダリングに反映されることで、既存のクロージャは影響を受けず、新しいクロージャが作成されるということです。 . 現在の状態では、フック内の値は既存のクロージャによって取得され、再レンダリングが起こったときに、関数が再び再作成されるかどうかに基づいてクロージャが更新されます。
を追加しても
setTimeout
関数では、再レンダリングが行われるであろう時間後にタイムアウトが実行されますが
setTimeout
は、更新された値ではなく、以前のクロージャの値をまだ使用します。
setMovies(result);
console.log(movies) // movies here will not be updated
状態の更新時にアクションを実行したい場合は、useEffectフックを使用する必要があります。
componentDidUpdate
useState が返すセッターはコールバックパターンを持たないため、クラスコンポーネントで使用されます。
useEffect(() => {
// action on update of movies
}, [movies]);
状態を更新する構文としては
setMovies(result)
は、以前の
movies
の値は、非同期リクエストから利用可能なものに変更されます。
しかし、レスポンスを以前に存在した値とマージしたい場合は、以下のようなスプレッド構文を正しく使用するとともに、状態更新のコールバック構文を使用する必要があります。
setMovies(prevMovies => ([...prevMovies, ...result]));
関連
-
[解決済み】webpack: モジュールが見つかりません。Error: 解決できない(相対パスで)
-
[解決済み】Javascriptのコールバック関数がFirefoxで「Callback is not a function」というエラーを投げる
-
[解決済み】Vueのテンプレートまたはレンダー関数が定義されていない 私はどちらも使っていないのですが?
-
[解決済み】Uncaught TypeError: 未定義のプロパティ 'msie' を読み取れない - jQuery tools
-
[解決済み】 \u003C とは何ですか?
-
[解決済み】react router v^4.0.0 Uncaught TypeError: 未定義のプロパティ'location'を読み取れない
-
[解決済み] TypeScriptでuseStateに型を設定するReact Hook
-
[解決済み] reactのsetStateメソッドを呼んでも、すぐにステートが変更されないのはなぜですか?
-
[解決済み】React HooksのPushメソッド(useState)?
-
[解決済み] useStateが再レンダリングのトリガーにならないのはなぜですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】TypeError: 'undefined'はオブジェクトではありません。
-
[解決済み】SecurityError: オリジンを持つフレームがクロスオリジンフレームにアクセスするのをブロックした
-
[解決済み】Angular JS Uncaught Error。[インジェクター:モジュラー]。
-
[解決済み】JavaScriptのgetElementByNameが機能しない
-
[解決済み】別のjsファイル内でJavaScriptの関数を呼び出す
-
[解決済み】Redux TypeError: 未定義のプロパティ 'apply' を読み取れない
-
[解決済み】JS ファイルが net::ERR_ABORTED 404 (Not Found) を取得する)
-
[解決済み】Vueのテンプレートまたはレンダー関数が定義されていない 私はどちらも使っていないのですが?
-
[解決済み】TypeError: AngularJSで未定義のプロパティ'get'を読み取れない
-
[解決済み] [Solved] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングする