[英]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/>
有一个包装器div
和input
元素。 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.