我要:
uploadImage
函数将文件的onDrop运行到Dropzone中。)我正在尝试确认我在第4步中拥有该映像,但是我无法通过控制台消息来确认。尽管日志消息显示状态已经更新,但我还是会停留在原始状态值上。
我尝试为所有内容添加额外的异步,并且将内容包装在promises中。我可以确认readImage
函数正常。我可以确认运行顺序是saveImage中的readImage
,saveImage
,setGraphic
,然后是uploadImage
中的console.log,应该具有更新的值,但没有更新的值。
const [graphic, setGraphic] = useState({ ...nullGraphic });
const readImage = async (img) => {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onerror = () => reader.abort();
reader.onabort = () => reject(new DOMException('Problem parsing input file.'));
reader.onload = () => resolve(reader.result);
reader.readAsDataURL(img);
});
};
const saveImage = async (img) => {
const imageRead = await readImage(img);
console.log(imageRead);
await setGraphic({
...graphic,
image: imageRead,
imageName: img.name,
imageType: img.type,
});
};
const uploadImage = async (img) => {
await saveImage(img);
console.log(graphic);
});
render() {
console.log(graphic);
return( <some dom> )
}
这是我奇怪的控制台序列:
Form.js:112 starting saveImage
Form.js:95 (snipped value of imageRead)
Form.js:237 {snipped updated values of graphic}
Form.js:114 done with saveImage
Form.js:116 {snipped original values of graphic}
我的理论
useState挂钩正在执行一些时髦的操作。
进程在启动时就复制该值,而不是在每次读取console.log时都读取它,因此uploadImage
函数在该进程的生存期内获取useState钩子的原始值。
答案 0 :(得分:0)
如果我们将所有那些React Magic简化为:p
function withState(initial, fn) {
function setState(updated) {
setTimeout(() => fn(updated, setState), 0);
//...
}
setState(initial);
}
现在我们可以说明会发生什么:
withState(0, (counter, setCount) => {
console.log("before", counter);
if(counter < 10) setCount(counter + 1);
console.log("after", counter);
});
如您所见,setCount
不会直接更改状态(count
)。实际上,它根本不会更改本地count
变量。因此,“之前”和“之后”将始终记录相同(只要您不直接突变counter
即可。)
将延迟调用setCount
(并在React中进行批处理),然后调用将整个组件函数传递给新计数。
因此,尝试await
setState调用是没有意义的,在状态之前和之后记录状态也是没有意义的(因为状态之间不会发生变化)。将其记录在组件中一次,如果您设置状态,则整个组件将再次执行,并且日志记录将记录新状态。