書き換えられたタイトルは次のとおりです。promise.then() の各 setState がレンダリングされる前に React Promise.all().then() を呼び出す
P粉162773626
P粉162773626 2023-08-20 11:02:53
0
1
334

テーブルに表示するためにリモート リソースに対して 200 件の呼び出しを実行しようとしています。同時に、残りの呼び出し数を示す進行状況バーを表示します。

この例を使用して、Fetch()Promise.all() を使用して setState()< を呼び出す方法を示します。 /code> 新しいデータを更新します。

私の問題は、各 Promise の .then() にあり、これは何らかのロジックを計算し、setState() を呼び出してデータを更新します。

私の進行状況バーは、Object.keys(data).length を使用して進行状況を表示します。

Promise.all() が「Complete」状態をトリガーし、進行状況バーが削除された後も、Promise 自体はまだ then() を呼び出しています。これにより、解決されたすべての Promise が表示される前に進行状況バーが非表示になります。

この問題に正しく対処するにはどうすればよいですか?


デモでは、setTimeout() を使用して、高価なロジックをシミュレートします。

問題は、Promise.all.then: 20Render 20 の後にある必要があることです。

レンダリング 0 ... レンダリング 12 Promise.all.then: 20 # 各レンダリング後にこれを記録する必要があります レンダリング 13 ... レンダリング 19 レンダリング 20 

デモで問題を示すために、進行状況バーが完全に埋まる前に削除されました (赤色に変わりました)。


const { useState } = React; const 例 = () => { const [done, setDone] = useState(false); const [データ, setData] = useState({}); const demoData = Array.from(Array(20).keys()); const demoResolver = (x) =>新しい Promise(res => setTimeout(() => res(x), Math.random() * 1250)) constloadData = () => { const Promise = DemonData.map(c =>demoResolver(c)); Promise.forEach(promise => { 約束 .then(r => { setTimeout(() => { setData(p => ({ ...p, [r]: r })); }, 500); }) }); Promise.all(約束) .then(r => { console.log('Promise.all.then: ', r.length) setDone(true); }) } console.log('Render', Object.keys(data).length); const progressBarIsShownDebugColor = (完了) ? 「危険です」 : '情報です'; 戻る ( <セクションクラス名='セクション'> 

{'例'}

<進捗状況 max="{demoData.length}" 値="{オブジェクト.キー(データ).長さ}" className="{'progress" my-3 ' progressBarIsShownDebugColor}> ) } ReactDOM.render(, document.getElementById("react"));
.as-console-wrapper { max-height: 50px !重要; }
 <リンク rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"> 


P粉162773626
P粉162773626

全員に返信 (1)
P粉426780515

上記のコードに示されている問題は、データを取得した後、状態を設定するまでにさらに 500 ミリ秒の非同期遅延が発生することです。実際のコードでは、.allの後にsetDataを呼び出す追加の処理 (おそらく同期) があるように見えます。

ベスト プラクティスは、doneを個別の状態ではなく計算プロパティとして持つことです。その時点では、競合を設定するために状態に依存する必要がなく、Object .keys( data).lengthは十分に安価であるため、パフォーマンスに悪影響を与えることはありません (また、他の領域でも使用できます。問題になった場合は、変数にキャッシュできます)。

リーリー

リーリー リーリー リーリー
いいねを押す+0
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート
    私たちについて 免責事項 Sitemap
    PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!