使用useState hook时如何将readAsDataURL.result的值更新到state?
问题核心原因
- useState的更新逻辑是异步批量更新,调用
setSelectedFile之后,当前渲染周期的selectedFile值不会立刻改变,你在reader.readAsDataURL之后同步打印的selectedFile还是更新前的旧值 FileReader.onload是异步回调,会在同步代码全部执行完之后才触发,所以你写在readAsDataURL后面的打印逻辑,执行时机远早于onload回调里的set操作,自然拿不到更新后的值
只要你在onload回调里打印的
event.target.result是正常的base64内容,set操作本身就是成功的,没有问题
正确实现方式
首先修改重名的参数避免作用域干扰,再通过useEffect监听state变化验证更新结果,后续业务逻辑也可以在监听回调里执行:
import { useState, useEffect } from 'react'; // 初始值设为null即可 const [selectedFile, setSelectedFile] = useState(null); const uploadFile = event => { const reader = new FileReader(); const file = event.target.files[0]; console.log('选中文件信息:', file); // 回调参数改名,避免和外层uploadFile的event参数冲突 reader.onload = (readerEvent) => { const fileBase64 = readerEvent.target.result; console.log('文件读取结果:', fileBase64); setSelectedFile(fileBase64); }; reader.readAsDataURL(file); }; // 监听selectedFile变化,获取更新后的值 useEffect(() => { if (selectedFile) { console.log('更新后的state值:', selectedFile); // 上传、预览等依赖最新selectedFile的逻辑可以写在这里 } }, [selectedFile]);
如果需要做图片预览,直接在JSX中使用selectedFile即可,state更新后组件会自动重渲染:
{selectedFile && <img src={selectedFile} alt="文件预览" />}
内容的提问来源于stack exchange,提问作者Mansoor Ishaq
相关产品推荐
相关产品推荐

