React + TypeScript实现上传整个文件夹
兼容性还有待测试,刚换了个电脑,环境还没配完……反正在不同的浏览器里是不太一样的,主要是在输入框的显示上,因为原生的实现在这一块不太一样;但是用还是能用的。今天下午突然收到私信,有人问我怎么在React里用TypeScript实现上传整个文件夹。其实这个还算是一个比较常见的场景,但是我并不太熟悉React,平时都是用Vue的,一时间还是有点懵。好在他提供了一个demo,大概长这样,就不写全了,..
兼容性还有待测试,刚换了个电脑,环境还没配完……反正在不同的浏览器里是不太一样的,主要是在输入框的显示上,因为原生的实现在这一块不太一样;但是用还是能用的。
今天下午突然收到私信,有人问我怎么在React里用TypeScript实现上传整个文件夹。其实这个还算是一个比较常见的场景,但是我并不太熟悉React,平时都是用Vue的,一时间还是有点懵。好在他提供了一个demo,大概长这样,就不写全了,意思到了就行:
<input type='file' ref='customAttributes'/>
componentDidMount(){
var input = ReactDOM.findDOMNode(this.refs.customAttributes)
input.setAttribute('webkitdirectory', '')
input.setAttribute('directory', '')
input.setAttribute('multiple', '')
}
看起来还是不错的(而且长得还有点像Vue),但是很不幸的是,这个API已经过时了。以下来自React中文网:
如果你之前使用过 React,你可能了解过之前的 API 中的 string 类型的 ref 属性,例如
"textInput"
。你可以通过this.refs.textInput
来访问 DOM 节点。我们不建议使用它,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除。
那么,怎么解决呢?其实还是比较简单的,使用createRef
方法创建一个可响应的ref。然后,因为用的是ts,可能需要在类型上做一些处理。第一次写,可能不是很优雅,请读者见谅:
class FileUploader extends React.Component {
private readonly uploader: React.RefObject<HTMLInputElement>;
constructor(props: {}) {
super(props);
this.uploader = React.createRef();
}
componentDidMount() {
this.uploader.current!.setAttribute('webkitdirectory', '');
this.uploader.current!.setAttribute('directory', '');
this.uploader.current!.setAttribute('multiple', '');
}
render() {
return (
<input type='file' ref={this.uploader}/>
);
}
}
mount方法里出现的!
是ts的非空断言,表示前面的元素一定不为空值;因为ref绑定的DOM元素可能是空值,比如还没加载,或者已经被销毁了。我们这里在mount里调用的时候,是一定不为空值的,就可以通过这个来绕开ts的空值检查。
但是这个看起来还是有点臃肿。为了一个简单的input,需要写这么多代码,尤其是constructor,很明显跟我们的目的无关。那么,能不能省略呢?答案显然是可以的。其实我比较喜欢React的一点就是它的函数式组件,而且有了hook之后,在写的时候就更有意思了:
function FunctionalFileUploader() {
const uploader = useCallback((node: HTMLInputElement) => {
node.setAttribute('webkitdirectory', '');
node.setAttribute('directory', '');
node.setAttribute('multiple', '');
}, []);
return (
<input type='file' ref={uploader}/>
)
}
用了个useCallback的hook,明显要比之前的优雅很多,而且还可以避免空值判断(虽然这个只是单纯的类型层面的事情)。
事情到了这里就算是结束了。再多嘴一句,想起Vue 3的语法,和这个简直如出一辙。果然前端大融合是个趋势啊……
更多推荐
所有评论(0)