一、是什麼
我們將元件間通訊可以拆分為兩個詞:
- 元件
- 通訊
回顧Vue系列的文章,元件是vue
中最強大的功能之一,同樣元件化是React
的核心思想
相比vue
,React
的元件更加靈活和多樣,按照不同的方式可以分成很多型別的元件
而通訊指的是傳送者通過某種媒體以某種格式來傳遞資訊到收信者以達到某個目的,廣義上,任何資訊的交通都是通訊
元件間通訊即指元件通過某種方式來傳遞資訊以達到某個目的
二、如何通訊
元件傳遞的方式有很多種,根據傳送者和接收者可以分為如下:
- 父元件向子元件傳遞
- 子元件向父元件傳遞
- 兄弟元件之間的通訊
- 父元件向後代元件傳遞
- 非關係元件傳遞
父元件向子元件傳遞
由於React
的資料流動為單向的,父元件向子元件傳遞是最常見的方式
父元件在呼叫子元件的時候,只需要在子元件標籤內傳遞引數,子元件通過props
屬性就能接收父元件傳遞過來的引數
function EmailInput(props) { return ( <label> Email: <input value={props.email} /> </label> ); } const element = <EmailInput email="123124132@163.com" />;
子元件向父元件傳遞
子元件向父元件通訊的基本思路是,父元件向子元件傳一個函式,然後通過這個函式的回撥,拿到子元件傳過來的值
父元件對應程式碼如下:
class Parents extends Component { constructor() { super(); this.state = { price: 0 }; } getItemPrice(e) { this.setState({ price: e }); } render() { return ( <div> <div>price: {this.state.price}</div> {/* 向子元件中傳入一個函式 */} <Child getPrice={this.getItemPrice.bind(this)} /> </div> ); } }
子元件對應程式碼如下:
class Child extends Component { clickGoods(e) { // 在此函式中傳入值 this.props.getPrice(e); } render() { return ( <div> <button onClick={this.clickGoods.bind(this, 100)}>goods1</button> <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button> </div> ); } }
兄弟元件之間的通訊
如果是兄弟元件之間的傳遞,則父元件作為中間層來實現資料的互通,通過使用父元件傳遞
class Parent extends React.Component { constructor(props) { super(props) this.state = {count: 0} } setCount = () => { this.setState({count: this.state.count + 1}) } render() { return ( <div> <SiblingA count={this.state.count} /> <SiblingB onClick={this.setCount} /> </div> ); } }
父元件向後代元件傳遞
父元件向後代元件傳遞資料是一件最普通的事情,就像全域性資料一樣
使用context
提供了元件之間通訊的一種方式,可以共享資料,其他資料都能讀取對應的資料
通過使用React.createContext
建立一個context
const PriceContext = React.createContext('price')
context
建立成功後,其下存在Provider
元件用於建立資料來源,Consumer
元件用於接收資料,使用例項如下:
Provider
元件通過value
屬性用於給後代元件傳遞資料:
<PriceContext.Provider value={100}> </PriceContext.Provider>
如果想要獲取Provider
傳遞的資料,可以通過Consumer
元件或者或者使用contextType
屬性接收,對應分別如下:
class MyClass extends React.Component { static contextType = PriceContext; render() { let price = this.context; /* 基於這個值進行渲染工作 */ } }
Consumer
元件:
<PriceContext.Consumer> { /*這裡是一個函式*/ } { price => <div>price:{price}</div> } </PriceContext.Consumer>
非關係元件傳遞
如果元件之間關係型別比較複雜的情況,建議將資料進行一個全域性資源管理,從而實現通訊,例如redux
。關於redux
的使用後續再詳細介紹
三、總結
由於React
是單向資料流,主要思想是元件不會改變接收的資料,只會監聽資料的變化,當資料發生變化時它們會使用接收到的新值,而不是去修改已有的值
因此,可以看到通訊過程中,資料的儲存位置都是存放在上級位置中