[英]Stopping event propagation in Reactjs
我正在嘗試創建一個父子組件。 子組件,在我的例子中, <Person/>
有一個包裝器div
和input
元素。 我有一個div
的單擊事件和配置的input
的更改事件。
我需要點擊事件來刪除這個人,而當我輸入輸入時,它應該更新名稱。 出於某種原因,當我開始在輸入字段中輸入時,這兩個事件都會被觸發。 我嘗試使用preventDefault()
和stopPropagation()
取消事件,但不起作用。 任何幫助將不勝感激。
請找到下面的演示代碼。
(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>
我相信你應該只需要在輸入元素的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 => { 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>
停止事件傳播僅適用於同一事件。 在您的情況下 - onClick
事件。
您可以在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>
另一種方法是檢查目標(如果您不想為輸入添加額外的處理程序)。
onClickParent(e) {
if (e.target.tagName !== "INPUT") {
console.log("onClickParent");
}
}
您也可以簡單地將您的輸入放在您的 div 之外。 (你可能有理由把它放在里面......只是想提一下......)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.