Як вручну викликати подію клацання в ReactJS?


97

Як я можу вручну викликати подію клацання в ReactJS ? Коли користувач натискає елемент1, я хочу автоматично викликати клацання по 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

@tobiasandersen Це цілком дійсний випадок програмування фокусування inputелемента, який, ймовірно, і хоче виконати запитувач за допомогою програмно викликаного клацання.
Джон Вайс

Так, звичайно, як фокус, так і розмиття цілком справедливі. Але клацання? Причиною, яку я запитую, є те, що якщо, наприклад, фокусування - це варіант використання, то краще це показати. Але якщо клік справді є варіантом використання, то краще просто зателефонувати обробнику.
tobiasandersen

@JohnWhite Ну, це могло бути правильно пов'язано :) Але ти, мабуть, маєш рацію, і це було не моє значення, щоб відірватися хитромудро. Просто хотів побачити, який справжній намір був за цим.
tobiasandersen

Відповіді:


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 Дякую оооооочень, це спрацювало для мене, у мене була необхідність обробляти клацання поза формою, тому що я ненавиджу помістити деякі елементи між кнопкою та формою.
Markus Ethur

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;

Це схоже на більш реагуючу відповідь.
Ritik

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, рекомендується помістити сюди хоча б відповідний код (до речі: редактор фрагментів також підтримує responsejs)
Icepickle

4
Варто зазначити, що, хоча підхід string рядок не є застарілим, він вважається застарілою функціональністю, яка витісняється синтаксисом на основі зворотного виклику: 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

Ось рішення Hooks

    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 (новий MouseEvent ('клацніть', {перегляд: вікно, бульбашки: true, скасовується: true, кнопки: 1,}),); Це має спрацювати
jackbridger

1

Посилаючись на відповідь Аарона Хакали з використанням Ref, натхненний цією відповіддю 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 знаходиться в React
Нітін Кумар,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.