Heim > Fragen und Antworten > Hauptteil
P粉4398045142023-09-03 16:06:45
因此,这确实取决于代码的执行方式,特别是 setState 的异步性质,因此您可以使用 setState 的回调形式。这是一个例子:
setBlobs(prevBlobs => [...prevBlobs, res._bodyBlob]);
这是包含其余代码的完整示例:
const capturePhoto = async () => { const photo = await camera.current.takePhoto(); fetch(photo.path) .then(res => { setBlobs(prevBlobs => [...prevBlobs, res._bodyBlob]); console.log('blobs', blobs.length, blobs); }) .catch(err => { console.log('err', err); }); checkLength(); }; const checkLength = async () => { if (blobs.length >= 2) { // upload files to a folder with the current date in a firebase cloud bucket const datestring = new Date().toLocaleString('de-DE'); blobs.forEach((blob, i) => { uploadFile(blob, datestring + '/' + (i + 1) + '.jpg'); }); // reset state setBlobs([]); sendNotification('Photos uploaded'); toggleDialog(); } };
P粉7757237222023-09-03 16:04:09
看起来像三件事:
checkLength
。setState
的新值。这是 React 的基本思想(是否是个好主意还有待商榷),状态值在渲染期间是不可变的。 setState
只是给出下一个渲染将使用的下一个不可变状态。setState
依赖于先前的状态时,您应该将回调传递给setState
,而不是直接使用当前值。举个例子,假设你有一个空数组,你调用 fetch 一次,然后在第一个数组完成之前再次调用 fetch 。在执行 ...blob
时,这两个 setState
调用都会引用空数组。通过传递回调,setState
获取作为参数传入的最新值。更多信息: https://react.dev/reference/react/Component#setstate 最简单的解决方案是将数组作为参数传递给 setState
回调内的 checkLength
。
这是问题中的 .then()
:
const capturePhoto = async () => { const photo = await camera.current.takePhoto(); fetch(photo.path) .then(res => { setBlobs(prev => { const newBlobs = [...prev, res._bodyBlob]; console.log('blobs', newBlobs.length, newBlobs); checkLength(newBlobs); return newBlobs; }); }) .catch(err => { console.log('err', err); }); };
这是async
await
const capturePhoto = async () => { const photo = await camera.current.takePhoto(); const res = await fetch(photo.path).catch(console.error); if (!res) return; setBlobs(prev => { const newBlobs = [...prev, res._bodyBlob]; console.log('blobs', newBlobs.length, newBlobs); checkLength(newBlobs); return newBlobs; }); };
检查长度
const checkLength = async (newBlobs) => { if (newBlobs.length >= 2) { // upload files to a folder with the current date in a firebase cloud bucket const datestring = new Date().toLocaleString('de-DE'); newBlobs.forEach((blob, i) => { uploadFile(blob, datestring + '/' + (i + 1) + '.jpg'); }); // reset state setBlobs([]); sendNotification('Photos uploaded'); toggleDialog(); } };