How to trigger INPUT FILE event REACTJS by another DOM

后端 未结 6 963
-上瘾入骨i
-上瘾入骨i 2021-01-02 01:53

I have a INPUT BUTTON and INPUT FILE, I want to click the BUTTON and it will trigger the INPUT FILE event

相关标签:
6条回答
  • 2021-01-02 02:18

    Using Hooks with useref:

    import React, {useRef} from 'react';
    const FancyInput = () => {
        const fileInput = useRef(null)
    
        const handleClick = () => {
            fileInput.current.click()
        }
    
        const handleFileChange = event => {
            console.log("Make something")
        }
    
        return(
            <div className="patientactions-container">
                <input
                    type="file"
                    onChange={(e) => handleFileChange(e)}
                    ref={fileInput} 
                />
                <div onClick={() => handleClick()}></div>
            </div>
        )
    }
    export default FancyInput;
    
    0 讨论(0)
  • 2021-01-02 02:24

    You don't need jQuery for this. You don't even need an event handler. HTML has a specific element for this, called label.

    First, make sure your input element has an id attribute:

    React.createElement('input',{type:'file', name:'myfile', id:'myfile'})
    

    Then, instead of:

    React.createElement('a',{onClick: this.doClick},'Select File')
    

    Try:

    React.createElement('label',{htmlFor: 'myfile'},'Select File')
    

    (Instead of adding htmlFor and id attributes, another solution is to make the input element a child of the label.)

    Now clicking the label should trigger the same behaviour as clicking the input itself.

    0 讨论(0)
  • 2021-01-02 02:26

    You could trigger the input type file with ref, f.e:

    on your class component:

    <input 
        ref={fileInput => this.fileInput = fileInput} 
        type="file"
     />
    <button onClick={this.triggerInputFile}> Select File </button>
    

    and make a function on that class component too:

    triggerInputFile = () => this.fileInput.click()
    
    0 讨论(0)
  • 2021-01-02 02:33

    Using useRef Hook in functional components. Requires React ^16.8,

    const Dummy = () => {
      const inputFileRef = useRef( null );
    
      const onFilechange = ( e ) => {
        /*Selected files data can be collected here.*/
        console.log( e.target.files );
      }
      const handleBtnClick = () => {
        /*Collecting node-element and performing click*/
        inputFileRef.current.click();
      }
    
      return (
        <form className="some-container">
          <input
            type="file"
            ref={inputFileRef}
            onChange={onFileChange}
          />
          <button onClick={onBtnClick}>Select file</button>
        </form >
      )
    }
    

    Class Implementation with React.createRef() and handling click with node element.

    class Dummy extends React.Component {
        
      constructor( props ) {
        super( props );
    
        this.inputFileRef = React.createRef();
        this.onFileChange = this.handleFileChange.bind( this );
        this.onBtnClick = this.handleBtnClick.bind( this );
      }
    
      handleFileChange( e ) {
        /*Selected files data can be collected here.*/
        console.log( e.target.files );
      }
    
      handleBtnClick() {
        /*Collecting node-element and performing click*/
        this.inputFileRef.current.click();
      }
    
      render() {
        return (
          <form className="some-container">
            <input
              type="file"
              ref={this.inputFileRef}
              onChange={this.onFileChange}
            />
            <button onClick={this.onBtnClick}>Select file</button>
          </form>
        )
      }
    }
    
    0 讨论(0)
  • 2021-01-02 02:34

    Building on the answer from @YÒGÎ , here is an implementation using TypeScript:

    class Dummy extends React.Component {
        fileInputRef: React.RefObject<HTMLInputElement> = React.createRef();
    
        forwardClickToInputElement = () => {
            this.fileInputRef.current!.click();
        };
    
        handleUploadDemand = (ie: ChangeEvent<HTMLInputElement>) => {
            const fileList: FileList = ie.target.files;
    
            // do something with the FileList, for example:
            const fileReader = new FileReader();
            fileReader.onload = () => {
                const str = String(fileReader.result);
                try {
                    const parsedContent = YOUR_OWN_PARSING(str);
                } catch (error) {
                    // YOUR OWN ERROR HANDLING
                }
            };
            fileReader.readAsBinaryString(fileList[0])
        }
    
        render() {
            return (
                <div className="some-container">
                    <button onClick={this.forwardClickToInputElement}>Select File</button>
                    <input ref={this.fileInputRef} type="file" onChange={this.handleSelectFile} hidden={true}/>
                </div>
            )
        }
    }
    

    References:

    1. Solution for how to use refs in React with Typescript https://stackoverflow.com/a/50505931/2848676
    2. Use ! operator for ref type narrowing https://medium.com/@martin_hotell/react-refs-with-typescript-a32d56c4d315
    0 讨论(0)
  • 2021-01-02 02:36

    EDIT: This is a question I answered a long time ago not knowing very much react at this time. The fun thing is that it has been considered valid ^^.

    So for anyone reading this answer; this answer is wrong and is a very good example of something you shouldn't do in react.

    Please find below a nice anti-pattern, again, don't do it.

    =================================================

    You can achieve this using jQuery:

    this.doClick: function() {
        $('input[type=file]').trigger('click');
    }
    

    React does not provide specific functions to trigger events, you can use jQuery or simply native Javascript: see Creating and triggering events on MDN

    0 讨论(0)
提交回复
热议问题