จะทริกเกอร์เหตุการณ์คลิกด้วยตนเองใน 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
Ahmed Nuaman

ฉันไม่เห็นว่าทำไมคุณถึงอยากทำสิ่งนี้ใน React คุณต้องการทำอะไร?
tobiasandersen

@tobiasandersen เป็นกรณีการใช้งานที่ถูกต้องอย่างสมบูรณ์ในการโฟกัสinputองค์ประกอบโดยทางโปรแกรมซึ่งเป็นไปได้ว่าผู้ถามต้องการบรรลุผลด้วยการคลิกที่ถูกกระตุ้นโดยโปรแกรม
John Weisz

ใช่ว่าทั้งโฟกัสและเบลอนั้นใช้ได้อย่างสมบูรณ์แบบ แต่คลิก? เหตุผลที่ฉันถามคือถ้าเช่นการโฟกัสเป็นกรณีการใช้งานแสดงว่าดีกว่า แต่ถ้าการคลิกเป็นกรณีการใช้งานจริงๆก็ควรเรียกตัวจัดการ
tobiasandersen

@JohnWhite มันสามารถผูกได้อย่างถูกต้อง :) แต่คุณอาจจะถูกและมันไม่ใช่ความหมายของฉันที่จะหลุดออกมาอย่างน่าอาย แค่อยากจะเห็นว่าความตั้งใจจริงเบื้องหลังคืออะไร
tobiasandersen

คำตอบ:


121

คุณสามารถใช้refprop เพื่อรับข้อมูลอ้างอิงไปยังอ็อบเจ็กต์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-node ที่แท้จริง


7
นี่ใช้ไม่ได้สำหรับฉัน ไม่แน่ใจว่ามันล้าสมัยหรือไม่ แต่ฉันกำหนดองค์ประกอบสำเร็จแล้ว แต่เมื่อฉันเรียกclickใช้มันclickไม่ได้กำหนดไว้ ฉันสามารถดูแอตทริบิวต์และการเรียกกลับอื่น ๆ ทั้งหมดที่ฉันกำหนดให้กับองค์ประกอบนั้นได้ ความคิดใด ๆ ?
TheJKFever

40
"Refs ไม่ส่งคืนโหนด DOM ของเอกสารอีกต่อไป แต่จะส่งคืนการอ้างอิงไปยัง React virtual DOM node" นั่นเป็นความเข้าใจผิดอย่างแน่นอน Refs ไม่ส่งคืนโหนด "virtual DOM" ที่มา: ฉันทำงานกับ React
Dan Abramov

4
@DanAbramov แล้ววิธีที่แนะนำสำหรับสิ่งนี้คืออะไร?
แผงหน้าปัด

1
@JohnWeisz ขอบคุณมากมันใช้ได้ผลสำหรับฉันฉันมีความจำเป็นที่จะต้องจัดการกับการคลิกนอกฟอร์มเพราะฉันต้องใส่องค์ประกอบบางอย่างระหว่างปุ่มและแบบฟอร์ม
Markus Ethur

1
ใช้ได้ผลสำหรับฉัน ฉันใส่องค์ประกอบอินพุตที่ -100 ด้วยตำแหน่งที่แน่นอนจากนั้นในรหัสref={(ref)=>{this.fileUploadRef = ref}ของฉันแล้วปุ่มของฉันonClick={()=>{this.fileUploadRef.click()}}
Richard

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

การตั้งค่าrefไปยังdivโหนด

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

ตรวจสอบซอ

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

หวังว่าจะช่วยได้!


เมื่อคุณเชื่อมโยงไปยัง jsfiddle ก็ถือเป็นแนวทางปฏิบัติที่ดีในการใส่โค้ดที่เกี่ยวข้องอย่างน้อยที่นี่ (btw: ตัวแก้ไขตัวอย่างข้อมูลรองรับ reactjs ด้วย)
Icepickle

4
มันเป็นที่น่าสังเกตว่าในขณะที่วิธีการสตริงเตะจะไม่เลิกก็ถือว่าการทำงานเดิมที่ถูกแทนที่โดยไวยากรณ์โทรกลับตาม: ref={elem => this.elem = elem}- นี้เป็นรายละเอียดในRefs การชิ้นส่วน
John Weisz

1
@JohnWhite ข้อเสนอแนะที่ถูกต้อง อัพเดทคำตอบ!
Pranesh Ravi

นอกจากนี้คุณต้องตรวจสอบและตรวจสอบให้แน่ใจว่าไม่ได้elเป็นโมฆะ / ไม่ได้กำหนดก่อนที่จะทำเช่นนั้น
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

ใช้ตอบสนองตะขอและเบ็ด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 ใหม่ ('คลิก', {view: window, bubble: true, ยกเลิกได้: จริง, ปุ่ม: 1,}),); มันควรจะทำงาน
jackbridger

1

ใช้คำตอบของ Aaron Hakala ด้วย 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 อยู่ใน React
Nitin Kumar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.