Как вручную вызвать событие клика в ReactJS?


97

Как я могу вручную вызвать событие щелчка в ReactJS ? Когда пользователь нажимает на element1, я хочу автоматически запускать щелчок по inputтегу.

<div className="div-margins logoContainer">
  <div id="element1" className="content" onClick={this.uploadLogoIcon}>
    <div className="logoBlank" />
  </div>
  <input accept="image/*" type="file" className="hide"/>
</div>

Глядя на некоторые внешние библиотеки, кажется хорошей идеей создать элемент ввода программно: github.com/okonet/react-dropzone/blob/master/src/index.js#L7
Ахмед Нуаман

Я не понимаю, зачем вам вообще нужно делать это в React. Что ты хочешь делать?
tobiasandersen 07

@tobiasandersen Это вполне допустимый вариант использования для программной фокусировки inputэлемента, что, вероятно, является тем, что запрашивающий хочет выполнить с помощью программно запускаемого щелчка.
Джон Вайс

Да, и фокус, и размытие вполне допустимы. Но щелчок? Причина, по которой я спрашиваю, заключается в том, что если, например, фокусировка является вариантом использования, то лучше это показать. Но если щелчок действительно является вариантом использования, то лучше просто вызвать обработчик.
tobiasandersen 07

@JohnWhite Ну, это могло быть правильно связано :) Но вы, вероятно, правы, и я не собирался показаться язвительным. Просто хотел увидеть, каковы были настоящие намерения этого.
tobiasandersen 07

Ответы:


121

Вы можете использовать refопору для получения ссылки на базовый объект HTMLInputElement через обратный вызов, сохранить ссылку как свойство класса, а затем использовать эту ссылку для последующего запуска щелчка из ваших обработчиков событий с помощью метода HTMLElement.click .

В вашем renderметоде:

<input ref={input => this.inputElement = input} ... />

В вашем обработчике событий:

this.inputElement.click();

Полный пример:

class MyComponent extends React.Component {
  render() {
    return (
      <div onClick={this.handleClick}>
        <input ref={input => this.inputElement = input} />
      </div>
    );
  }

  handleClick = (e) => {
    this.inputElement.click();
  }
}

Обратите внимание на стрелочную функцию ES6, которая обеспечивает правильную лексическую область для thisобратного вызова. Также обратите внимание, что объект, который вы получаете таким образом, является объектом, похожим на то, что вы получили бы с помощью document.getElementById, то есть фактическим DOM-узлом.


7
У меня это не работает. Не уверен, что он устарел, но я успешно назначаю элемент, но когда я вызываю clickего, clickон не определен. Я могу видеть все остальные атрибуты и обратные вызовы, которые я назначил этому элементу. Любые идеи?
TheJKFever

40
«Ссылки больше не возвращают узел DOM документа, они возвращают ссылку на виртуальный узел DOM React» Это определенно заблуждение. Ссылки не возвращают "виртуальные DOM" узлы. Источник: работаю над React.
Дан Абрамов

4
@DanAbramov Итак, какой метод рекомендуется для этого?
приборная панель

1
@JohnWeisz Огромное спасибо, у меня это сработало, у меня возникла необходимость обрабатывать щелчок вне формы, потому что мне приходилось помещать некоторые элементы между кнопкой и формой.
Маркус Этур

1
Работает для меня. Я поместил элемент ввода на -100 с абсолютной позицией, затем в свой код, ref={(ref)=>{this.fileUploadRef = ref}а затем в свою кнопкуonClick={()=>{this.fileUploadRef.click()}}
Ричард

20

Получил следующее для работы в мае 2018 года с ES6 React Docs в качестве ссылки: https://reactjs.org/docs/refs-and-the-dom.html

import React, { Component } from "react";
class AddImage extends Component {
  constructor(props) {
    super(props);
    this.fileUpload = React.createRef();
    this.showFileUpload = this.showFileUpload.bind(this);
  }
  showFileUpload() {
    this.fileUpload.current.click();
  }
  render() {
    return (
      <div className="AddImage">
        <input
          type="file"
          id="my_file"
          style={{ display: "none" }}
          ref={this.fileUpload}
        />
        <input
          type="image"
          src="http://www.graphicssimplified.com/wp-content/uploads/2015/04/upload-cloud.png"
          width="30px"
          onClick={this.showFileUpload}
        />
      </div>
    );
  }
}
export default AddImage;

Это похоже на ответ, ориентированный на реакцию.
Ритик

8

Вы можете использовать refобратный вызов, который вернет node. Вызов click()этого узла для выполнения программного щелчка.

Получение divузла

clickDiv(el) {
  el.click()
}

Установка a refдля divузла

<div 
  id="element1"
  className="content"
  ref={this.clickDiv}
  onClick={this.uploadLogoIcon}
>

Проверьте скрипку

https://jsfiddle.net/pranesh_ravi/5skk51ap/1/

Надеюсь, это поможет!


когда вы ссылаетесь на jsfiddle, считается хорошей практикой помещать сюда хотя бы соответствующий код (кстати: редактор фрагментов также поддерживает reactjs)
Icepickle

4
Стоит отметить, что, хотя подход со ссылкой на строку не является устаревшим, он считается устаревшей функциональностью, которая заменяется синтаксисом на основе обратного вызова: ref={elem => this.elem = elem}- Это подробно описано в ссылках на компоненты .
Джон Вайс,

1
@JohnWhite Действительное предложение. Обновил ответ!
Пранеш Рави

Кроме того, перед этим вам нужно проверить и убедиться, что elэто не null / undefined.
janex

4

В функциональном компоненте этот принцип также работает, просто это немного другой синтаксис и способ мышления.

const UploadsWindow = () => {
  // will hold a reference for our real input file
  let inputFile = '';

  // function to trigger our input file click
  const uploadClick = e => {
    e.preventDefault();
    inputFile.click();
    return false;
  };

  return (
    <>
      <input
        type="file"
        name="fileUpload"
        ref={input => {
          // assigns a reference so we can trigger it later
          inputFile = input;
        }}
        multiple
      />

      <a href="#" className="btn" onClick={uploadClick}>
        Add or Drag Attachments Here
      </a>
    </>
  )

}

2

Попробуйте это и дайте мне знать, если это не сработает с вашей стороны:

<input type="checkbox" name='agree' ref={input => this.inputElement = input}/>
<div onClick={() => this.inputElement.click()}>Click</div>

Щелчок по значку divдолжен имитировать щелчок по inputэлементу.


2

Вот решение крючков

    import React, {useRef} from 'react';

    const MyComponent = () =>{

    const myRefname= useRef(null);

    const handleClick = () => {
        myRefname.current.focus();
     }

    return (
      <div onClick={handleClick}>
        <input ref={myRefname}/>
      </div>
     );
    }

«myRefname.current.focus не является функцией»
Spoderman4

1

Использование React Hooks и useRefхука .

import React, { useRef } from 'react';

const MyComponent = () => {
    const myInput = useRef(null);

    const clickElement = () => {
        // To simulate a user focusing an input you should use the
        // built in .focus() method.
        myInput.current?.focus();

        // To simulate a click on a button you can use the .click()
        // method.
        // myInput.current?.click();
    }

    return (
        <div>
            <button onClick={clickElement}>
                Trigger click inside input
            </button>
            <input ref={myInput} />
        </div>
    );
}

Для меня это не сработало, так как щелчок и фокус были недоступны. Но что сработало, так это ответ stackoverflow.com/a/54316368/3893510, если вместо попытки выполнить myInput.current? .Click (); Вы делаете: myInput.current.dispatchEvent (new MouseEvent ('щелчок', {вид: окно, пузыри: true, cancelable: true, buttons: 1,}),); Это должно сработать
jackbridger

1

Риффы на ответ Аарон Хакала с useRef вдохновлены этим ответом https://stackoverflow.com/a/54316368/3893510

const myRef = useRef(null);

  const clickElement = (ref) => {
    ref.current.dispatchEvent(
      new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true,
        buttons: 1,
      }),
    );
  };

И ваш JSX:

<button onClick={() => clickElement(myRef)}>Click<button/>
<input ref={myRef}>

0

Если это не работает в последней версии reactjs, попробуйте использовать innerRef

class MyComponent extends React.Component {


  render() {
    return (
      <div onClick={this.handleClick}>
        <input innerRef={input => this.inputElement = input} />
      </div>
    );
  }

  handleClick = (e) => {
    this.inputElement.click();
  }
}

0

  imagePicker(){
        this.refs.fileUploader.click();
        this.setState({
            imagePicker: true
        })
    }
  <div onClick={this.imagePicker.bind(this)} >
  <input type='file'  style={{display: 'none'}}  ref="fileUploader" onChange={this.imageOnChange} /> 
  </div>

Эта работа для меня


-2

Как насчет простого старого js? пример:

autoClick = () => {
 if (something === something) {
    var link = document.getElementById('dashboard-link');
    link.click();
  }
};
  ......      
var clickIt = this.autoClick();            
return (
  <div>
     <Link id="dashboard-link" to={'/dashboard'}>Dashboard</Link>
  </div>
);

Expectaion находится в реакции
Нитин Кумар
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.