簡體   English   中英

在 Reactjs 中停止事件傳播

[英]Stopping event propagation in Reactjs

我正在嘗試創建一個父子組件。 子組件,在我的例子中, <Person/>有一個包裝器divinput元素。 我有一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM