上传同一文件时onUpload未触发,是否是useCallback和useEffect使用错误?
问题根因
你遇到的重复上传同名文件不触发onUpload的问题,和useCallback、useEffect的使用无关,根因为原生文件选择框的默认特性:当用户选中的文件路径与input当前的value属性存储的路径完全一致时,onChange事件不会触发,自然不会走到后续的setFiles和上传逻辑。
修复方案
你只需要对现有代码做少量调整即可解决问题,同时优化你提到的调用逻辑问题:
核心修改点
- 每次打开文件选择器前,主动清空file input的value,保证即使选择同一文件也能触发onChange
- 可选择移除冗余的files状态,减少不必要的组件重渲染
- 调整onUpload为接收文件列表参数,简化useCallback依赖
修复后完整代码
export const UploadAssets = (props) => { const fileInput = useRef<HTMLInputElement>(null); useEffect(() => { // 原有逻辑保持不变 }, []); const onChooseFile = (e) => { e.preventDefault(); if (fileInput?.current) { props.options.onStart(); // 新增:清空input value,解决同文件二次选择不触发问题 fileInput.current.value = ''; fileInput.current.click(); } } const onUpload = useCallback((files: FileList) => { if (!files) return false; const formData = new FormData(); for (let i = 0; i < files.length; i++) { const file = files[i]; formData.append(file.name, file); } const xhr = new XMLHttpRequest(); xhr.open('post', myUrl, true); xhr.send(formData); return true; }, []); const onChangeFile = (e) => { e.preventDefault(); const selectedFiles = e.target.files; if (selectedFiles) { props.options.onChooseFile(selectedFiles); // 直接调用上传,不需要经过state中转 onUpload(selectedFiles); } } return ( <div> <button onClick={onChooseFile}>Upload File</button> <input type="file" ref={fileInput} onChange={onChangeFile} hidden/> </div> ); }
额外说明
如果你需要保留files状态用于页面展示(比如显示已选文件列表),也可以不删除files状态和对应的监听useEffect,只需要在onChooseFile方法里加fileInput.current.value = ''这一行即可解决重复上传的问题。
内容的提问来源于stack exchange,提问作者Nouh Belahcen
相关产品推荐
相关产品推荐

