如何在React Dropzone中编程触发onDrop处理其他组件传入的文件
解决方案
方案1:逻辑抽离(最推荐)
不需要强制触发Dropzone组件的onDrop回调,你可以把文件处理逻辑和校验逻辑单独抽成公共方法,外部prop传入文件时,校验通过后直接调用该方法即可,性能最优且不依赖Dropzone内部实现,后续版本升级也不会出现兼容问题。
示例代码如下:
// 复用和Dropzone规则一致的文件校验逻辑 const validateFiles = (files) => { const accepted = [] const rejected = [] Array.from(files).forEach(file => { if (file.type === 'application/pdf') { accepted.push(file) } else { rejected.push(file) } }) return { accepted, rejected } } class YourComponent extends React.Component { // 原有的文件处理逻辑 handleDrop = (files, setFieldValue, setSubmitting) => { // 原有业务代码 } // 监听外部传入的文件prop变化 componentDidUpdate(prevProps) { // 假设外部传入的文件prop名为externalFiles if (this.props.externalFiles && prevProps.externalFiles !== this.props.externalFiles) { const { accepted } = validateFiles(this.props.externalFiles) if (accepted.length) { // 直接调用处理逻辑,和onDrop触发效果完全一致 this.handleDrop(accepted, this.props.setFieldValue, this.props.setSubmitting) } } } render() { return ( <Dropzone multiple={true} accept={['application/pdf']} onDrop={files => this.handleDrop(files, this.props.setFieldValue, this.props.setSubmitting) } > {({ getRootProps, getInputProps }) => ( <div {...getRootProps()} className="drop-border" > <input {...getInputProps()} /> <div>Drop a pdf document here or click to select one</div> </div> )} </Dropzone> ) } }
方案2:手动触发内部input事件(复用Dropzone原生校验)
如果你不想自己写校验逻辑,需要完全复用Dropzone自带的文件校验能力,可以通过ref获取Dropzone内部的input元素,手动赋值文件并触发change事件,Dropzone会自动执行onDrop回调。
示例代码如下:
class YourComponent extends React.Component { // 创建ref存储Dropzone内部的input元素 dropzoneInputRef = React.createRef() // 监听外部传入的文件prop变化 componentDidUpdate(prevProps) { if (this.props.externalFiles && prevProps.externalFiles !== this.props.externalFiles) { // 给input赋值外部传入的文件 this.dropzoneInputRef.current.files = this.props.externalFiles // 触发change事件,Dropzone会自动执行校验和onDrop回调 this.dropzoneInputRef.current.dispatchEvent(new Event('change', { bubbles: true })) } } render() { return ( <Dropzone multiple={true} accept={['application/pdf']} onDrop={files => this.handleDrop(files, setFieldValue, setSubmitting) } > {({ getRootProps, getInputProps }) => ( <div {...getRootProps()} className="drop-border" > {/* 把ref通过getInputProps传入,获取内部input引用,属于Dropzone官方支持的用法 */} <input {...getInputProps({ ref: this.dropzoneInputRef })} /> <div>Drop a pdf document here or click to select one</div> </div> )} </Dropzone> ) } }
内容的提问来源于stack exchange,提问作者Ferdous Jahan
相关产品推荐
相关产品推荐

