React受控File输入组件重渲染后失效报错排查
解决React受控File Input重渲染后失效的问题
我来帮你搞定这个React里file input的坑!你遇到的这个报错,本质是浏览器的安全限制在搞鬼——浏览器绝对不允许通过JS给type为file的input设置非空的value值,只能设成空字符串。
为啥会报错?
你代码里把event.target.value存在了state里,可这个值其实是浏览器伪造的假路径(比如C:\fakepath\xxx.jpg),根本不是真实的文件路径。当组件因为显示/隐藏切换重渲染时,React会尝试把这个假路径赋值给input的value属性,直接撞在了浏览器的安全规则上,自然就抛出错误了。
而且说实话,event.target.value对于文件操作没啥用,真正的文件数据都存在event.target.files里呢。
两种解决方案,按需选
方案1:改用非受控组件(最推荐)
因为file input的特殊性,其实完全没必要把它做成受控组件,用ref直接拿文件就行,这样就不会碰value赋值的雷区:
import { useRef } from 'react'; function YourComponent() { const fileInputRef = useRef(null); const handleFileChange = (event) => { const selectedFiles = event.target.files; // 这里处理选中的文件,比如存到state里方便后续使用 // setFiles(Array.from(selectedFiles)); }; // 如果需要重置输入框,直接给value设空就行 const resetFileInput = () => { if (fileInputRef.current) { fileInputRef.current.value = ''; } }; return ( <div> <input ref={fileInputRef} id="1" name="file input" type="file" multiple onChange={handleFileChange} /> {/* 这里放你切换显示/隐藏的组件逻辑 */} </div> ); }
方案2:非要用受控逻辑?也能搞(不推荐)
如果硬要结合state跟踪文件,那记住value必须固定为空字符串,用state存选中的文件对象而不是那个假路径:
import { useState } from 'react'; function YourComponent() { const [selectedFiles, setSelectedFiles] = useState([]); const handleFileChange = (event) => { const files = Array.from(event.target.files); setSelectedFiles(files); // 别再存那个没用的event.target.value了! }; return ( <div> <input id="1" name="file input" type="file" value="" {/* 固定死为空字符串 */} multiple onChange={handleFileChange} /> {/* 可以给用户显示选中的文件名 */} {selectedFiles.length > 0 && ( <div> 已选文件: {selectedFiles.map((file, idx) => ( <span key={idx}>{file.name}</span> ))} </div> )} </div> ); }
最后提醒
不管用哪种方案,只要保证组件重渲染时,file input的value要么不设置(非受控),要么设为空字符串,就不会再触发那个讨厌的错误啦。另外,以后处理文件时,直接用event.target.files拿文件对象才是正确姿势,那个假路径真的没用~
内容的提问来源于stack exchange,提问作者Unknown
相关产品推荐
相关产品推荐

