我是React的新手,正在尝试构建一个我想按自定义按钮的应用程序,它将打开一个文件对话框并在选择它时上传文件。这是我的代码:
class ComposeButtons extends Component{
constructor(props) {
super(props);
this.state={
selectedFile: null
};
this.myInput = React.createRef();
}
fileSelectedHandler = (event) => {
console.log(event.target.files[0]);
this.setState({
selectedFile: event.target.files[0]
})
};
triggerClick = () => {
this.myInput.current.click()
};
fileUploadHandler = () => {
/* file upload triggered */
console.log('file upload triggered');
};
render() {
return(
<div className={"composeForm-area"}>
<div>
<Input
style={{display:'none'}}
type={"file"}
onChange={this.fileSelectedHandler}
ref={this.myInput}
/>
<Button onClick={this.triggerClick}
onChange={this.fileUploadHandler}
style={{ backgroundColor: '#DDDCDC'}}>
<Icon style={{ fontSize: '20px'}} type="camera" />
</Button>
</div>
</div>
)
}
}
export default ComposeButtons;
我当前的输出:
但是,我只会得到如上所示的可点击图标,但是单击它会抛出:
Uncaught TypeError: _this.myInput.current.click is not a function
at eval (ComposeButtons.js:88)
at Button._this.handleClick (button.js:143)
at HTMLUnknownElement.callCallback (react-dom.development.js:14
我想要的:
当我单击此相机按钮时,我只是想打开一个文件对话框来选择文件,并且在文件对话框中选择并按OK后,它应该关闭并触发fileUploadHandler
功能,以便在控制台上打印消息。仅此而已!
我尝试过的事情:
除了上面的代码,我还尝试使用以下代码替换render方法中div中的代码:
<div>
<Input
id="myInput"
style={{display:'none'}}
type={"file"}
onChange={this.fileSelectedHandler}
ref={(ref) => this.myInput = ref}
/>
<Button onClick={(e) => this.myInput.click() }
style={{ backgroundColor: '#DDDCDC'}}>
<Icon style={{ fontSize: '20px'}} type="camera" />
</Button>
</div>
我也遵循了关于stackoverflow的几乎所有答案,但似乎对我没有任何帮助。如果有人可以指出正确的方向,那将非常有帮助。
这是我在React中的第一个业余爱好项目。
答案 0 :(得分:3)
据我所知。我们所能做的就是使用label标签中的label
属性添加一个指向输入类型file
的{{1}}标签。这样我们就不需要使用for
有关此link中的信息。
现在所需要做的就是为ref
标签编写适当的CSS
label
之后,触发文件上传。我们可以在调用<div>
<label htmlFor="myInput"><Icon style={{ fontSize: '20px'}} type="camera" /></label>
<input
id="myInput"
style={{display:'none'}}
type={"file"}
onChange={this.fileSelectedHandler}
/>
</div>
之后再调用fileUploadHandler
。
fileSelectedHandler
答案 1 :(得分:0)
我建议您使用一个库而不是自己构建。只要您想做更多一点,处理文件就会很棘手。试用https://github.com/react-dropzone/react-dropzone。它很棒,并且易于使用。
答案 2 :(得分:0)
如果您可以使用钩子,那么有一个软件包可以解决您的问题。
https://www.npmjs.com/package/use-file-picker
import { useFilePicker } from 'use-file-picker';
function App() {
const [filesContent, errors, openFileSelector] = useFilePicker({
multiple: true,
accept: '.ics,.pdf',
});
if (errors.length > 0) return <p>Error!</p>;
return (
<div>
<button onClick={() => openFileSelector()}>Reopen file selector</button>
<pre>{JSON.stringify(filesContent)}</pre>
</div>
);
}
我创建这个钩子的原因和你一样。