React结合Cloudinary上传图片时FileReader相关报错求助
问题排查与修复:React图片预览的两个错误
错误原因分析
1. reader.onloadend is not a function at privewFile
onloadend是FileReader的事件属性,需要赋值一个函数,而非像调用方法那样执行它。你的代码中写成reader.onloadend(() => {...}),错误地将该属性覆盖为undefined,从而触发报错。
2. Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'
React的setState是异步操作,在handleFile里调用setFile(pic)后,立刻使用state中的file,此时file还是旧的null值,并非刚选中的文件对象。你传给privewFile的是这个null,自然不符合readAsDataURL要求的Blob类型参数。
另外还有拼写错误:privewFile应为previewFile(不影响功能,但属于代码规范问题)。
修正后的代码
export default function Register() { const [user, setUser] = useState({ username:"", email:"", password:"", age:0, gender:"", }) const [file, setFile] = useState(null) const [img,setImg] = useState("") const handleChange = (event) => { setUser({ ...user, [event.target.id]: event.target.value, }); } // 修正拼写:privewFile → previewFile function previewFile(file) { const reader = new FileReader() reader.readAsDataURL(file) // 修正:onloadend赋值函数,而非调用 reader.onloadend = () => { setImg(reader.result) } // 注意:此处console.log(img)会显示旧值,因setState是异步操作 // 如需查看更新后的值,可通过useEffect监听img变化 } const handleFile = (event) => { if (event.target.files && event.target.files[0]) { const pic = event.target.files[0] setFile(pic) // 修正:直接传入刚获取的pic,而非state中的file previewFile(pic) } } const handleSubmit = (event) => { event.preventDefault() console.log(user); console.log(file); } return ( <div className='container'> <div className='left'> <div className='logo'> <DatabaseNetworkPoint theme="outline" size="150" fill="#333"/> <h1>WonderHit</h1> </div> <form className='form' onSubmit={handleSubmit}> <input placeholder='Username' id='username' value={user.username} className='field' type="text" onChange={handleChange} /> <input placeholder='Email' id='email' value={user.email} className='field' type="email" onChange={handleChange} /> <input placeholder='Password' id='password' value={user.password} className='field' type="password" onChange={handleChange} /> <input placeholder='Age' id='age' value={user.age} className='field' type="number" onChange={handleChange} /> <input placeholder='Gender' id='gender' value={user.gender} className='field' type="text" onChange={handleChange} /> <div className='profilePic'> <div className='Photo'> <img className='Photo' src={img} /> </div> <input className='field2' id='file' type="file" accept=".png, .jpg, .jpeg" onChange={(e) => handleFile(e)} /> <label htmlFor = "file" className='uploadPic' >+</label> </div> <button className='submit' type="submit">Register</button> <h3 className='routing'>You already have an account ? <Link className='rot' to="/">Login</Link></h3> </form> </div> <img className='right' src='https://images.unsplash.com/photo-1562577309-4932fdd64cd1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074&q=80' /> </div> ) }
额外说明
如果需要查看img更新后的值,不要直接在previewFile内console.log(img),可添加useEffect监听:
useEffect(() => { console.log(img); }, [img])
后续对接Cloudinary上传时,直接使用state中的file对象即可,它会正确保存选中的文件。
内容的提问来源于stack exchange,提问作者Naser Atmeh
相关产品推荐
相关产品推荐

