React非巢狀元件通訊
非巢狀元件: 就是沒有任何包含關係的元件,包括兄弟元件以及不再同一個父級的非兄弟元件 針對這種情況的元件通訊,常用兩種方式處理
利用二者共同父級元件的context物件進行通訊 列表內容 自定義事件方式進行通訊
第一種方式所使用的context物件類似一個全域性變數,有可能會造成全域性汙染,官方也是推薦儘可能不使用.
下面說說第二種使用方式,其實也非常簡單,類似angular中的服務依賴注入的方式. 這種方式需要使用用來自定義事件的event包,下面先安裝 javascript 程式碼
npm install event -S
或者
yarn add event
元件結構: App元件為根元件,根元件裡面有兩個兄弟元件,Child1,Child2, 用於在Child1和Child2元件進行通訊的Event服務.下面實現Child1元件與Child2元件之間的通訊
Event.js(服務) javascript 程式碼
import {EventEmitter} from 'events'; //這裡並沒有使用jsx的語法,所以不用匯入React
export default new EventEmitter(); App元件 javascript 程式碼
import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; import Child1 from './views/Child1'; import Child2 from './views/Child2';
class App extends Component { render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1> </header>
<Child1 /> <Child2 /> </div> ); } }
export default App;
Child1元件 javascript 程式碼
import React, {Component} from 'react'; import emitter from '../services/event';
class Child extends Component { constructor() { super(); this.handleClick = this.handleClick.bind(this); } handleClick() { emitter.emit('callMe', 'Hello'); } render() { return ( <button onClick={this.handleClick}>event click</button> ); } }
export default Child;
Child2元件 javascript 程式碼
import React, {Component} from 'react'; import emitter from '../services/event';
class Parent extends Component { constructor() { super(); } componentDidMount() { this.eventEmitter = emitter.addListener('callMe', (msg) => { console.log(msg); }); } componentWillUnmount() { emitter.removeListener(this.eventEmitter); } render() { return ( <p>Parent Component</p> ); } }
export default Parent;