เพื่อเรียกใช้งานกิจกรรมการเปลี่ยนแปลงหลังจากกดปุ่ม Enter


204

ฉันใหม่สำหรับ Bootstrap และติดอยู่กับปัญหานี้ ฉันมีช่องป้อนข้อมูลและทันทีที่ฉันป้อนเพียงหนึ่งหลักฟังก์ชันจากonChangeนั้นจะถูกเรียกใช้ แต่ฉันต้องการให้มันถูกเรียกเมื่อฉันกด 'Enter เมื่อป้อนหมายเลขทั้งหมดแล้ว ปัญหาเดียวกันสำหรับฟังก์ชั่นการตรวจสอบ - มันเรียกเร็วเกินไป

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
  //bsStyle: this.validationInputFactor(),
  placeholder: this.initialFactor,
  className: "input-block-level",
  onChange: this.handleInput,
  block: true,
  addonBefore: '%',
  ref:'input',
  hasFeedback: true
});

คำตอบ:


404

ตามการตอบสนองหมอคุณสามารถฟังเหตุการณ์แป้นพิมพ์เหมือนonKeyPressหรือไม่onKeyUponChange

var Input = React.createClass({
  render: function () {
    return <input type="text" onKeyDown={this._handleKeyDown} />;
  },
  _handleKeyDown: function(e) {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }
});

อัปเดต: ใช้ React.Component

นี่คือรหัสที่ใช้ React.Component ซึ่งทำสิ่งเดียวกัน

class Input extends React.Component {
  _handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }

  render() {
    return <input type="text" onKeyDown={this._handleKeyDown} />
  }
}

นี่คือjsfiddle

อัปเดต 2: ใช้องค์ประกอบที่ใช้งานได้

const Input = () => {
  const handleKeyDown = (event) => {
    if (event.key === 'Enter') {
      console.log('do validate')
    }
  }

  return <input type="text" onKeyDown={handleKeyDown} />
}

2
และคุณต้องการผูกกระบวนการตรวจสอบกับonBlurเหตุการณ์
wuct

5
วิธีการแก้ปัญหาแบบเดียวกันในขนาดกะทัดรัดมากขึ้นโดยอ้างอิงถึงข้อความอินพุต:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind

5
@musemind refที่จริงแล้วคุณไม่จำเป็นต้องใช้ <input onKeyPress={e => doSomething(e.target.value)}เพียงพอแล้ว
39675 Wuct

4
@musemind จุดที่จะใช้วิธีการเรียนแทนฟังก์ชั่นแบบอินไลน์คือการหลีกเลี่ยงการสร้างฟังก์ชั่นใหม่ทุกครั้งเมื่อonKeyPressมีการทริกเกอร์ เป็นการปรับปรุงที่สมบูรณ์แบบ
wuct

1
ซอที่แนบมาไม่ทำงานอีกต่อไปโปรดตรวจสอบคำตอบที่ดีอยู่แล้ว
Pardeep Jain

52

คุณสามารถใช้ onKeyPress โดยตรงในช่องใส่ ฟังก์ชั่น onChange เปลี่ยนค่าสถานะในทุกการเปลี่ยนแปลงเขตข้อมูลอินพุตและหลังจากกด Enter มันจะเรียกการค้นหาฟังก์ชั่น ()

<input
    type="text"
    placeholder="Search..."
    onChange={event => {this.setState({query: event.target.value})}}
    onKeyPress={event => {
                if (event.key === 'Enter') {
                  this.search()
                }
              }}
/>

คำตอบนี้ใช้ได้สำหรับฉันมากกว่าคำตอบที่ยอมรับด้านบน
karthik shankar

หากคุณมีรูปแบบหนักฉันขอแนะนำให้สร้างฟังก์ชั่นนอกวิธีการแสดงผลและผ่านมันเป็นข้อมูลอ้างอิงเช่นonKeyPress={this.yourFunc}มิฉะนั้นฟังก์ชั่นลูกศรไขมันจะถูกสร้างขึ้นใหม่ในแต่ละการแสดงผล
Viktor

สิ่งนี้ใช้ได้กับกรณีที่เหตุการณ์ onKeyPress ถูกเขียนสำหรับอินพุตและพาเรนต์เคสด้วย ขอบคุณ
Naveen Kumar PG

หรือonKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid

24

การกด Enterเมื่อโฟกัสในตัวควบคุมฟอร์ม (อินพุต) โดยปกติจะทริกเกอร์เหตุการณ์submit(onSubmit) บนฟอร์มเอง (ไม่ใช่อินพุต) ดังนั้นคุณสามารถผูกthis.handleInputฟอร์มของคุณกับ onSubmit ได้

หรือคุณอาจผูกมันไว้กับblurเหตุการณ์ (onBlur) inputที่เกิดขึ้นเมื่อลบโฟกัส (เช่นการแท็บไปที่องค์ประกอบถัดไปที่สามารถโฟกัสได้)


3
onKeyPressนี้อยู่ไกลสะอาดกว่าการใช้
Blackus

1
คิดว่าเนื่องจากเป้าหมายแตกต่างกันevent.target.valueไม่สามารถใช้ได้
Izkata

@ Izkata สิ่งที่คุณพูดถูกต้องอย่างแน่นอน; คำตอบของฉันอาจต้องใช้วิธีอื่นในการจัดการสิ่งต่าง ๆ ในhandleInputวิธีการควบคุม ทำตามคำตอบของฉันจะครอบคลุมคุณทั้งสองเมื่อผู้ใช้กดป้อนในขณะที่มุ่งเน้นไปที่การป้อนข้อมูลและเมื่อเปิดใช้งานsubmitปุ่ม / อินพุต
Luca

ในสถานการณ์ส่วนใหญ่ในเว็บแอปไม่มีรูปแบบเพียงอินพุตดังนั้นคำตอบนี้ไม่เกี่ยวข้องกับกรณีการใช้งานส่วนใหญ่ IMHO
vsync

@vsync อาจไม่เกี่ยวข้องกับคนส่วนใหญ่ แต่ก็ยังคงใช้ได้สำหรับบางส่วน - และไม่ถูกต้องแน่นอนฉันไม่คิดว่ามันคุ้มค่ากับการลงคะแนนใช่ไหม
Luca

8

คุณสามารถใช้ได้ event.key

function Input({onKeyPress}) {
  return (
    <div>
      <h2>Input</h2>
      <input type="text" onKeyPress={onKeyPress}/>
    </div>
  )
}

class Form extends React.Component {
  state = {value:""}

  handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      this.setState({value:e.target.value})
    }
  }

  render() {
    return (
      <section>
        <Input onKeyPress={this.handleKeyPress}/>
        <br/>
        <output>{this.state.value}</output>
      </section>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById("react")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>


5

ตอบสนองผู้ใช้ต่อไปนี้เป็นคำตอบสำหรับความครบถ้วนสมบูรณ์

ทำปฏิกิริยารุ่น 16.4.2

คุณต้องการอัปเดตสำหรับทุกการกดแป้นพิมพ์หรือรับค่าเมื่อส่งเท่านั้น การเพิ่มเหตุการณ์สำคัญในการทำงานของส่วนประกอบ แต่มีทางเลือกตามที่แนะนำในเอกสารอย่างเป็นทางการ

ควบคุมเทียบกับส่วนประกอบที่ไม่ได้รับการควบคุม

ควบคุม

จากเอกสาร - ฟอร์มและส่วนประกอบที่ควบคุม :

ใน HTML องค์ประกอบของฟอร์มเช่นอินพุต textarea และเลือกโดยทั่วไปจะรักษาสถานะของตนเองและอัปเดตตามการป้อนข้อมูลของผู้ใช้ ใน React โดยทั่วไปสถานะที่ไม่แน่นอนจะถูกเก็บไว้ในคุณสมบัติสถานะของส่วนประกอบและอัปเดตเฉพาะกับ setState ()

เราสามารถรวมสองสิ่งนี้เข้าด้วยกันโดยทำให้สถานะของปฏิกิริยาเป็น“ แหล่งเดียวของความจริง” จากนั้นองค์ประกอบ React ที่แสดงผลแบบฟอร์มจะควบคุมสิ่งที่เกิดขึ้นในแบบฟอร์มนั้นในการป้อนข้อมูลผู้ใช้ครั้งต่อไป องค์ประกอบรูปแบบการป้อนข้อมูลที่มีค่าถูกควบคุมโดย React ด้วยวิธีนี้เรียกว่า "องค์ประกอบที่ควบคุม"

หากคุณใช้องค์ประกอบที่ควบคุมคุณจะต้องปรับปรุงสถานะสำหรับการเปลี่ยนแปลงค่าทุกครั้ง เพื่อให้สิ่งนี้เกิดขึ้นคุณผูกตัวจัดการเหตุการณ์กับคอมโพเนนต์ ในตัวอย่างของเอกสารมักจะเป็นเหตุการณ์ onChange

ตัวอย่าง:

1) ผูกตัวจัดการเหตุการณ์ในตัวสร้าง (ค่าที่เก็บไว้ในสถานะ)

constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
}

2) สร้างฟังก์ชั่นจัดการ

handleChange(event) {
    this.setState({value: event.target.value});
}

3) สร้างฟังก์ชั่นส่งแบบฟอร์ม (ค่าถูกนำมาจากรัฐ)

handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
}

4) แสดงผล

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
</form>

หากคุณใช้ส่วนประกอบที่มีการควบคุมhandleChangeฟังก์ชั่นของคุณจะถูกเปิดใช้งานเสมอเพื่ออัปเดตและรักษาสถานะที่เหมาะสม รัฐจะมีค่าที่อัพเดทอยู่เสมอและเมื่อมีการส่งแบบฟอร์มค่าจะถูกนำมาจากรัฐ นี่อาจเป็นข้อโต้แย้งหากรูปแบบของคุณยาวมากเพราะคุณจะต้องสร้างฟังก์ชั่นสำหรับทุกองค์ประกอบหรือเขียนแบบง่าย ๆ ที่จัดการกับการเปลี่ยนแปลงขององค์ประกอบทุกค่า

ไม่มีการควบคุม

จากเอกสาร - องค์ประกอบที่ไม่สามารถควบคุมได้

ในกรณีส่วนใหญ่เราแนะนำให้ใช้ส่วนประกอบที่ควบคุมเพื่อใช้แบบฟอร์ม ในองค์ประกอบที่ควบคุมข้อมูลในแบบฟอร์มจะถูกจัดการโดยองค์ประกอบ React ทางเลือกคือส่วนประกอบที่ไม่สามารถควบคุมได้ซึ่ง DOM จัดการข้อมูลในแบบฟอร์ม

ในการเขียนองค์ประกอบที่ไม่สามารถควบคุมได้แทนที่จะเขียนตัวจัดการเหตุการณ์สำหรับการอัพเดททุกสถานะคุณสามารถใช้การอ้างอิงเพื่อรับค่าฟอร์มจาก DOM

ความแตกต่างหลักที่นี่คือคุณไม่ได้ใช้onChangeฟังก์ชั่น แต่เป็นonSubmitรูปแบบของการรับค่าและตรวจสอบถ้าจำเป็น

ตัวอย่าง:

1) ผูกตัวจัดการเหตุการณ์และสร้างการอ้างอิงไปยังอินพุตในตัวสร้าง (ไม่มีค่าเก็บไว้ในสถานะ)

constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
}

2) สร้างฟังก์ชั่นการส่งแบบฟอร์ม (ค่านำมาจากองค์ประกอบ DOM)

handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
}

3) แสดงผล

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" ref={this.input} />
    </label>
    <input type="submit" value="Submit" />
</form>

หากคุณใช้ส่วนประกอบที่ไม่มีการควบคุมคุณไม่จำเป็นต้องผูกhandleChangeฟังก์ชันใด ๆ เมื่อมีการส่งแบบฟอร์มค่าจะถูกนำมาจาก DOM และการตรวจสอบความถูกต้องที่จำเป็นสามารถเกิดขึ้นได้ ณ จุดนี้ ไม่จำเป็นต้องสร้างฟังก์ชั่นตัวจัดการสำหรับองค์ประกอบอินพุตใด ๆ เช่นกัน

ปัญหาของคุณ

ตอนนี้สำหรับปัญหาของคุณ:

... ฉันต้องการให้มันถูกเรียกเมื่อฉันกด 'Enter เมื่อมีการป้อนหมายเลขทั้งหมด

หากคุณต้องการทำสิ่งนี้ให้ใช้องค์ประกอบที่ไม่สามารถควบคุมได้ อย่าสร้างตัวจัดการ onChange หากไม่จำเป็น enterที่สำคัญจะส่งแบบฟอร์มและhandleSubmitฟังก์ชั่นจะถูกไล่ออก

การเปลี่ยนแปลงที่คุณต้องทำ:

ลบการโทร onChange ในองค์ประกอบของคุณ

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
    //    bsStyle: this.validationInputFactor(),
    placeholder: this.initialFactor,
    className: "input-block-level",
    // onChange: this.handleInput,
    block: true,
    addonBefore: '%',
    ref:'input',
    hasFeedback: true
});

จัดการกับการส่งแบบฟอร์มและตรวจสอบความถูกต้องของคุณ คุณต้องได้รับค่าจากองค์ประกอบของคุณในฟังก์ชั่นส่งแบบฟอร์มและจากนั้นตรวจสอบ ตรวจสอบให้แน่ใจว่าคุณสร้างการอ้างอิงถึงองค์ประกอบของคุณในตัวสร้าง

  handleSubmit(event) {
      // Get value of input field
      let value = this.input.current.value;
      event.preventDefault();
      // Validate 'value' and submit using your own api or something
  }

ตัวอย่างการใช้องค์ประกอบที่ไม่สามารถควบคุมได้:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    // bind submit function
    this.handleSubmit = this.handleSubmit.bind(this);
    // create reference to input field
    this.input = React.createRef();
  }

  handleSubmit(event) {
    // Get value of input field
    let value = this.input.current.value;
    console.log('value in input field: ' + value );
    event.preventDefault();
    // Validate 'value' and submit using your own api or something
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);

3

คุณสามารถเขียนฟังก์ชัน wrapper เล็กน้อยเช่นนี้

const onEnter = (event, callback) => event.key === 'Enter' && callback()

จากนั้นกินมันในอินพุตของคุณ

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.