setState を使用して配列をリセットできないのはなぜですか?
P粉714890053
P粉714890053 2023-09-02 23:44:06
0
2
579
<p>カメラ コンポーネントで、3 枚目ごとに写真をバケットにアップロードしたいと考えています。 React で状態を使用して画像 BLOB を配列に保存しています。最初の 3 枚の写真はすべて正常に機能しますが、それ以降は配列を空にリセットできず、一見ランダムな数の写真がバケットにアップロードされます。 </p> <pre class="brush:js;toolbar:false;"> let [blobs, setBlobs] = useState([]); const CapturePhoto = async () => { const photo = await カメラ.current.takePhoto(); フェッチ(写真.パス) .then(res => { setBlobs([...blobs, res._bodyBlob]); console.log('blobs', blob.length, blob); }) .catch(err => { console.log('err', err); }); checkLength(); }; const checkLength = async () => { if (blobs.length >= 2) { // Firebase クラウド バケット内の現在の日付のフォルダーにファイルをアップロードします const datestring = new Date().toLocaleString('de-DE'); blob.forEach((blob, i) => { UploadFile(blob, datestring '/' (i 1) '.jpg'); }); // 状態をリセット setBlobs([]); sendNotification('写真がアップロードされました'); トグルダイアログ(); } }; </pre> <p>コンソール経由でアレイのログを記録しましたが、サイズは増加するだけでした。また、要素を追加したにもかかわらず、コンソールのログ記録が最初から開始されます。これは、おそらく <code>setState()</code> が非同期であるためです。 Promiseでラップしてリセットを待ってみましたが、残念ながらそれもうまくいきませんでした。 3 つの BLOB がある場合、それらをクラウドにアップロードし、後でリストをリセットするにはどうすればよいですか? </p>
P粉714890053
P粉714890053

全員に返信(2)
P粉439804514

つまり、実際にはコードの実行方法、特に setState の非同期の性質に依存するため、setState のコールバック形式を使用できます。以下に例を示します:

リーリー

コードの残りの部分を含む完全な例を次に示します:

リーリー
いいねを押す +0
P粉775723722

次の 3 つのことが考えられます:

  1. フェッチ呼び出しを待たずに、フェッチが完了する前に checkLength を呼び出します。
  2. 次回のレンダリングまで、setState の新しい値は取得されません。これは React の基本的な考え方であり (これが良いアイデアかどうかは議論の余地があります)、状態値はレンダリング中に不変です。 setState 次のレンダリングで使用される次の不変状態を与えるだけです。
  3. setState が以前の状態に依存する場合、現在の値を直接使用するのではなく、コールバックを setState に渡す必要があります。たとえば、空の配列があり、fetch を 1 回呼び出して、最初の配列が完了する前に再度 fetch を呼び出したとします。両方の setState 呼び出しは、...blob の実行時に空の配列を参照します。コールバックを渡すことにより、setState はパラメータとして渡された最新の値を取得します。詳細: https://react.dev/reference/react/Component#setstate

最も簡単な解決策は、setState コールバック内の checkLength にパラメータとして配列を渡すことです。

これは質問の .then() です:

リーリー

これは非同期 await

リーリー

長さの確認

リーリー
いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート