【问题标题】:How to trigger INPUT FILE event REACTJS by another DOM如何通过另一个 DOM 触发 INPUT FILE 事件 REACTJS
【发布时间】:2015-12-02 17:02:17
【问题描述】:

我有一个INPUT BUTTONINPUT FILE,我想点击BUTTON,它会触发INPUT FILEREACT JS 中的 /strong> 事件。

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

然后是按钮

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

那么当我们点击A HREF时如何定义和触发INPUT FILE点击事件呢?

感谢您的帮助。 :-)

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    更新:2021 年 9 月 18 日

    注意:在 NextJS 上,我面临 onChange 事件不是从输入文件元素触发的。为此,我们可以使用onInputCaptureonChangeCapture。更多详细信息,Stackoverflow - onChange event is not firing

    根据我们的要求,onChangeCapture 的基本示例。需要 React ^16.8,

    const Dummy = () => {
      const inputFileRef = React.useRef();
      const onFileChangeCapture = ( e: React.ChangeEvent<HTMLInputElement> ) {
        /*Selected files data can be collected here.*/
        console.log(e.target.files);
      };
      const onBtnClick = () => {
        /*Collecting node-element and performing click*/
        inputFileRef.current.click();
      };
      return (
        <form>
          <input
            type="file"
            ref={inputFileRef}
            onChangeCapture={onFileChangeCapture}
          />
          <button onClick={onBtnClick}>Select file</button>
        </form>
      );
    };
    

    在功能组件中使用 useRef Hook。需要 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 onBtnClick = () => {
        /*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>
      )
    }
    

    使用 React.createRef() 实现类并使用 node 元素处理点击。

    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>
        )
      }
    }
    

    【讨论】:

    • 这是正确的方法,理所当然应该是一个公认的答案。
    • 那么如何将上传的文件保存在状态变量中呢?我在输入中添加了一个 onChange 但它不起作用??
    • 使用输入标签中的 onChange 属性处理它。 &lt;input type="file" onChange={( e ) =&gt; e.target.files[0]} /&gt;More info
    • 你如何确保 ref 已被填充?它不会触发渲染,因此第一次渲染 ref 在功能组件中始终为 null。每次第一次重新渲染以获取 ref 实例是否被认为是最佳实践?
    • this.onBtnClick = this.handleBtnClick.bind(this); ====> 应该是 ====> this.onBtnClick = this.onBtnClick.bind( this );
    【解决方案2】:

    你不需要 jQuery。您甚至不需要事件处理程序。 HTML 对此有一个特定的元素,称为label

    首先,确保您的input 元素具有id 属性:

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

    然后,而不是:

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

    试试:

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

    (不添加htmlForid 属性,另一种解决方案是使input 元素成为label 的子元素。)

    现在单击label 应该会触发与单击input 本身相同的行为。

    【讨论】:

    • 谢谢您的好心先生!
    【解决方案3】:

    您可以使用 ref, f.e: 触发输入类型文件:

    在你的类组件上:

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

    并在该类组件上创建一个函数:

    triggerInputFile = () => this.fileInput.click()
    

    【讨论】:

      【解决方案4】:

      使用钩子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;
      

      【讨论】:

      • 我试过这个,但在尝试运行 fileInput.current.click() 时,我不断收到错误 Object is possibly 'null'.。我尝试使用 if 语句仅在 fileInput.current !== null 时运行它,但我仍然收到错误消息。有什么想法吗?
      【解决方案5】:

      基于@YÒGÎ 的答案,这里是使用 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>
              )
          }
      }
      

      参考资料:

      1. React with Typescript 中如何使用引用的解决方案https://stackoverflow.com/a/50505931/2848676
      2. 使用!用于 ref 类型缩小的运算符 https://medium.com/@martin_hotell/react-refs-with-typescript-a32d56c4d315

      【讨论】:

        【解决方案6】:

        编辑:这是我很久以前回答的一个问题,此时我不知道有多大反应。有趣的是它被认为是有效的^^。

        因此,对于阅读此答案的任何人; 这个答案是错误的,是一个很好的例子,说明你不应该在 react 中做一些事情。

        请在下面找到一个不错的反模式,再说一遍,不要这样做。

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

        您可以使用 jQuery 来实现:

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

        React 没有提供特定的函数来触发事件,你可以使用 jQuery 或者简单的原生 Javascript:见 MDN 上的Creating and triggering events

        【讨论】:

        • React.createElement('input',{type:'file', name:'myfile'}) 然后按钮 React.creatElement('a',{onClick: this.doClick},' Select File') 那么当我们点击A HREF时如何定义和触发INPUT FILE点击事件呢?
        • 是的,目前我总是这样做,但我需要找到有什么方法可以通过 REACT 而不是 JQUERY 触发
        • 使用 React 的原因是为了摆脱 jQuery。这个答案很差。
        • jQuery 完全控制了 DOM,而 react 则相反。强烈建议不要一起使用它们。
        猜你喜欢
        • 2019-02-01
        • 1970-01-01
        • 2015-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多