简体   繁体   English

在 Reactjs 中停止事件传播

[英]Stopping event propagation in Reactjs

I am trying to create a parent and child component.我正在尝试创建一个父子组件。 The child component, in my case, <Person/> has a wrapper div and input element.子组件,在我的例子中, <Person/>有一个包装器divinput元素。 I have a click event for the div and change event for the input configured.我有一个div的单击事件和配置的input的更改事件。

I need the click event to delete the person, whereas when I type in the input, it should update the name.我需要点击事件来删除这个人,而当我输入输入时,它应该更新名称。 For some reason, both the events are fired when i start typing in the input field.出于某种原因,当我开始在输入字段中输入时,这两个事件都会被触发。 I tried cancelling the event using preventDefault() and stopPropagation() but does not work.我尝试使用preventDefault()stopPropagation()取消事件,但不起作用。 Any help would be appreaciated.任何帮助将不胜感激。

Please find the below demo code.请找到下面的演示代码。

 (function () { class Person extends React.Component { render() { return ( <div onClick={this.props.onClickParent}> <h1>{this.props.name}: {this.props.age}</h1> <input value={this.name} onChange={this.props.onNameChange} onFocus={ ev => { ev.preventDefault(); ev.stopPropagation(); ev.nativeEvent.stopImmediatePropagation(); ev.nativeEvent.preventDefault(); ev.nativeEvent.stopPropagation(); this.props.onNameChange(); } } /> </div> ) } } class App extends React.Component { state = { people: [{ age: 36, id: 1, name: 'Jon' }, { age: 28, id: 2, name: 'Bob' }], } onNameChange() { console.log('onNameChange') } onClickParent() { console.log('onClickParent') } render() { return ( <div> { this.state.people.map(person => { return ( <Person name={person.name} age={person.age} key={person.id} onClickParent={this.onClickParent} onNameChange={this.onNameChange} /> ) }) } </div> ); } } ReactDOM.render( <App />, document.getElementById('root') ); })();
 <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="root"></div>

I believe you should just have to stop propagation in the onClick hander of the input element.我相信你应该只需要在输入元素的onClick中停止传播。 Does this work as intended?这是否按预期工作?

 (function () { class Person extends React.Component { render() { return ( <div onClick={this.props.onClickParent}> <h1>{this.props.name}: {this.props.age}</h1> <input value={this.name} onChange={this.props.onNameChange} onClick={e => { e.stopPropagation() }} onFocus={ ev => { this.props.onNameChange(); } } /> </div> ) } } class App extends React.Component { state = { people: [{ age: 36, id: 1, name: 'Jon' }, { age: 28, id: 2, name: 'Bob' }], } onNameChange() { console.log('onNameChange') } onClickParent() { console.log('onClickParent') } render() { return ( <div> { this.state.people.map(person => { return ( <Person name={person.name} age={person.age} key={person.id} onClickParent={this.onClickParent} onNameChange={this.onNameChange} /> ) }) } </div> ); } } ReactDOM.render( <App />, document.getElementById('root') ); })();
 <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="root"></div>

Stopping event propagation will work only for the same event.停止事件传播仅适用于同一事件。 In your case - the onClick event.在您的情况下 - onClick事件。

You can add a new onClick event on the input element and stop the propagation there:您可以在input元素上添加新的onClick事件并在那里停止传播:

 (function () { class Person extends React.Component { render() { return ( <div onClick={this.props.onClickParent}> <h1>{this.props.name}: {this.props.age}</h1> <input value={this.name} onChange={this.props.onNameChange} onClick={e=>e.stopPropagation()} onFocus={ ev => { ev.preventDefault(); ev.stopPropagation(); ev.nativeEvent.stopImmediatePropagation(); ev.nativeEvent.preventDefault(); ev.nativeEvent.stopPropagation(); this.props.onNameChange(); } } /> </div> ) } } class App extends React.Component { state = { people: [{ age: 36, id: 1, name: 'Jon' }, { age: 28, id: 2, name: 'Bob' }], } onNameChange() { console.log('onNameChange') } onClickParent() { console.log('onClickParent') } render() { return ( <div> { this.state.people.map(person => { return ( <Person name={person.name} age={person.age} key={person.id} onClickParent={this.onClickParent} onNameChange={this.onNameChange} /> ) }) } </div> ); } } ReactDOM.render( <App />, document.getElementById('root') ); })();
 <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="root"></div>

Another way is to check the target (if you don't want to add an extra handler for your input).另一种方法是检查目标(如果您不想为输入添加额外的处理程序)。

  onClickParent(e) {
    if (e.target.tagName !== "INPUT") {
      console.log("onClickParent");
    }
  }

Also you can simply have your input outside of your div.您也可以简单地将您的输入放在您的 div 之外。 (you might have your reasons for putting it inside.... just wanted to mention this...) (你可能有理由把它放在里面......只是想提一下......)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM