setState を使用して配列をリセットできないのはなぜですか?
P粉714890053
2023-09-02 23:44:06
<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>
つまり、実際にはコードの実行方法、特に setState の非同期の性質に依存するため、setState のコールバック形式を使用できます。以下に例を示します:
リーリーコードの残りの部分を含む完全な例を次に示します:
リーリー次の 3 つのことが考えられます:
checkLength
を呼び出します。setState
の新しい値は取得されません。これは React の基本的な考え方であり (これが良いアイデアかどうかは議論の余地があります)、状態値はレンダリング中に不変です。setState
次のレンダリングで使用される次の不変状態を与えるだけです。setState
が以前の状態に依存する場合、現在の値を直接使用するのではなく、コールバックをsetState
に渡す必要があります。たとえば、空の配列があり、fetch を 1 回呼び出して、最初の配列が完了する前に再度 fetch を呼び出したとします。両方のsetState
呼び出しは、...blob
の実行時に空の配列を参照します。コールバックを渡すことにより、setState
はパラメータとして渡された最新の値を取得します。詳細: https://react.dev/reference/react/Component#setstate最も簡単な解決策は、
setState
コールバック内のcheckLength
にパラメータとして配列を渡すことです。これは質問の
リーリー.then()
です:これは
リーリー非同期
await
リーリー長さの確認