React.js:将<input type =“ file”>转换为自定义按钮图标时出现问题

时间:2019-08-20 10:35:51

标签: javascript reactjs

我是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;

我当前的输出:

enter image description here

但是,我只会得到如上所示的可点击图标,但是单击它会抛出:

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中的第一个业余爱好项目。

3 个答案:

答案 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>
  );
}

我创建这个钩子的原因和你一样。