Jak ręcznie wywołać zdarzenie kliknięcia w ReactJS?

106

Jak ręcznie wywołać zdarzenie kliknięcia w ReactJS ? Gdy użytkownik kliknie element1, chcę automatycznie wywołać kliknięcie inputtagu.

<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>
Mamata Hegde
źródło
Patrząc na niektóre biblioteki zewnętrzne, dobrym pomysłem wydaje się programowe utworzenie
Ahmed Nuaman
Nie rozumiem, dlaczego kiedykolwiek chciałbyś to zrobić w React. Czego szukasz?
tobiasandersen
@tobiasandersen Idealnym przypadkiem użycia jest programowe skupienie się na inputelemencie, co jest prawdopodobnie tym, co pytający chce osiągnąć za pomocą kliknięcia wyzwalanego programowo.
John Weisz,
Jasne, zarówno ostrość, jak i rozmycie są całkowicie prawidłowe. Ale klikanie? Pytam dlatego, że jeśli np. Skupianie się jest przypadkiem użycia, to lepiej to pokazać. Ale jeśli kliknięcie naprawdę jest przypadkiem użycia, lepiej po prostu zadzwonić do programu obsługi.
tobiasandersen
@JohnWhite Cóż, to mogłoby być poprawnie związane :) Ale prawdopodobnie masz rację i nie miałem zamiaru odpuszczać. Chciałem tylko zobaczyć, jaki był prawdziwy zamiar tego.
tobiasandersen

Odpowiedzi:

128

Możesz użyć właściwości, refaby uzyskać odwołanie do bazowego obiektu HTMLInputElement za pomocą wywołania zwrotnego, zapisać odwołanie jako właściwość klasy, a następnie użyć tego odwołania, aby później wywołać kliknięcie ze swoich programów obsługi zdarzeń za pomocą HTMLElement.click metody .

W Twojej rendermetodzie:

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

W programie obsługi zdarzeń:

this.inputElement.click();

Pełny przykład:

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

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

Zwróć uwagę na funkcję strzałki ES6, która zapewnia prawidłowy zakres leksykalny thisw wywołaniu zwrotnym. Zauważ również, że obiekt, który zdobędziesz w ten sposób, jest obiektem podobnym do tego, co byś uzyskał używając document.getElementById, tj. Rzeczywisty węzeł DOM.

John Weisz
źródło
7
To nie działa dla mnie. Nie jestem pewien, czy jest nieaktualny, ale pomyślnie przypisałem element, ale kiedy clickgo clickwywołuję , jest niezdefiniowany. Widzę wszystkie inne atrybuty i wywołania zwrotne, które przypisałem do tego elementu. Jakieś pomysły?
TheJKFever
41
„Odwołania nie zwracają już węzła DOM dokumentu, zwracają odniesienie do wirtualnego węzła DOM React”. To zdecydowanie błędne przekonanie. Odniesienia nie zwracają węzłów „wirtualnego DOM”. Źródło: pracuję nad Reactem.
Dan Abramov
4
@DanAbramov Jaka jest więc zalecana metoda?
alegria
1
@JohnWeisz Bardzo dziękuję, zadziałało na mnie, miałem tę potrzebę obsługi kliknięciem poza formularzem, ponieważ musiałem wstawić kilka elementów między przyciskiem a formularzem.
Markus Ethur,
1
Pracuje dla mnie. Ustawiłem element wejściowy na -100 z pozycją bezwzględną, potem w moim kodzie, ref={(ref)=>{this.fileUploadRef = ref}a następnie w moim przyciskuonClick={()=>{this.fileUploadRef.click()}}
Richard
22

Do pracy w maju 2018 r. Z ES6 React Docs jako odniesieniem: 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;
Sir Codes Alot
źródło
To wygląda na odpowiedź bardziej zorientowaną na reakcję .
Ritik
8

Możesz użyć funkcji refzwrotnej, która zwróci plik node. Wywołaj click()ten węzeł, aby wykonać programowe kliknięcie.

Pobieranie divwęzła

clickDiv(el) {
  el.click()
}

Ustawienie a refdo divwęzła

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

Sprawdź skrzypce

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

Mam nadzieję, że to pomoże!

Pranesh Ravi
źródło
kiedy odwołują się do jsfiddle, to concidered dobra praktyka, aby umieścić co najmniej odpowiedni kod tutaj (BTW: Edytor fragment podpory reactjs również)
Icepickle
4
Warto zauważyć, że chociaż podejście string ref nie jest przestarzałe, jest uważane za starszą funkcjonalność, która jest zastępowana przez składnię opartą na wywołaniach zwrotnych: ref={elem => this.elem = elem}- Jest to szczegółowo opisane w Refs to Components .
John Weisz,
1
@JohnWhite Prawidłowa sugestia. Zaktualizowałem odpowiedź!
Pranesh Ravi
Ponadto musisz sprawdzić i upewnić się, że elnie jest null / undefined, zanim to zrobisz.
janex
6

W komponencie funkcjonalnym ta zasada również działa, to tylko trochę inna składnia i sposób myślenia.

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

}
Niezmienna cegła
źródło
3

Oto rozwiązanie hooków

    import React, {useRef} from 'react';

    const MyComponent = () =>{

    const myRefname= useRef(null);

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

    return (
      <div onClick={handleClick}>
        <input ref={myRefname}/>
      </div>
     );
    }
Sajad Saderi
źródło
„myRefname.current.focus nie jest funkcją”
Spoderman4
2

Spróbuj tego i daj mi znać, jeśli to nie zadziała:

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

Kliknięcie na divpowinno symulować kliknięcie inputelementu

Alex Oleksiiuk
źródło
1

Używanie haków React i useRefhooka .

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>
    );
}
Aaron Hakala
źródło
Dla mnie to nie działało, ponieważ kliknięcie i ostrość nie były dostępne. Ale co zadziałało, to ta odpowiedź, stackoverflow.com/a/54316368/3893510, jeśli zamiast próbować wykonać myInput.current? .Click (); Robisz: myInput.current.dispatchEvent (new MouseEvent ('click', {view: window, bubbles: true, cancellable: true, buttons: 1,}),); Powinno działać
jackbridger
1

Riffowanie odpowiedzi Aarona Hakali za pomocą useRef zainspirowane tą odpowiedzią 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,
      }),
    );
  };

I twój JSX:

<button onClick={() => clickElement(myRef)}>Click<button/>
<input ref={myRef}>
jackbridger
źródło
0

Jeśli to nie działa w najnowszej wersji reagjs, spróbuj użyć innerRef

class MyComponent extends React.Component {


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

  handleClick = (e) => {
    this.inputElement.click();
  }
}
mXaln
źródło
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>

Ta praca dla mnie

arslan
źródło
-2

A może zwykły stary js? przykład:

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>
);
taggartJ
źródło
Expectaion is in React
Nitin Kumar