父組件向孫子組件傳值(Context)特性


引言

在我們React組件開發中,當一個父組件的想要往自己的子孫組件傳值的時候,可以使用 props屬性,但是其每一個子組件,都要向下傳遞數據,這樣造成的數據的耦合性,所以在 React 官方文檔中 提供了 context特性來解決,這個問題。

父子組件之間的通信

我們先看一下React中,父子組件通信的機制,父子組件的通信是通過props進行數據的傳遞:

  1. 父組件向子組件傳遞數據(狀態)時,是在調用子組件的時候通過參數傳遞給子組件,子組件通過this.props進行接收;
  2. 子組件如果更改父組件的一些屬性,則是通過父組件定義的方法來傳遞給子組件,子組件調用更改;
  3. 如果父組件想要更改子組件的一些狀態時,通過ref進行標記,可以獲取子組件的所有信息,從而調用子組件的方法和值;

但是,如果層級很多呢,是否需要多個props進行逐層的傳遞?答案是否定的,React的advanced(高級)中指出了context,優雅的解決這個問題。

好的,接下來我們來介紹一下這個特性Context

我們知道,在JS中context指的是函數的執行上下文,函數被調用時,this指向誰,誰就是當前的執行上下文;

  1. react中的context是什么呢?官方文檔給出:
    • Context 通過組件樹提供了一個傳遞數據的方法,從而避免了在每一個層級手動的傳遞 props 屬性。

文檔也沒具體給出context到底是什么,而是告訴我們context能干什么,也就是說,如果我們不想通過props實現組件樹的逐層傳遞數據,則可以使用context實現跨層級進行數據傳遞!

如何使用 Context 呢?

context api給出三個概念:React.createContext()、Provider、Consumer;

  1. React.createContext()
這個方法用來創建context對象,並包含Provider、Consumer兩個組件 <Provider />、<Consumer />

const {Provider, Consumer} = React.createContext();
  1. Provider
數據的生產者,通過value屬性接收存儲的公共狀態,來傳遞給子組件或后代組件

eg:

<Provider value={/* some value */}>
  1. Consumer
數據的消費者,通過訂閱Provider傳入的context的值,來實時更新當前組件的狀態

eg: 

<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

值得一提的是每當Provider的值發生改變時, 作為Provider后代的所有Consumers都會重新渲染
props單向數據流動:

如果覺得Props傳遞數據很繁瑣,可以采用context,進行跨組件傳遞數據

再最外層的組件上,通過生產者Provider組件進行包裹,並存儲共享數據到value中,當然可以是任何數據類型。后帶需要用到共享數據的組件均可通過Consumer進行數據獲取

代碼演示


import React from 'react'
import ReactDOM from 'react-dom'

// 創建一個 textcont 特性的
const {Provider,Consumer} = React.createContext('頂頂頂')

class Person extends React.Component{
    constructor(props){
        super(props)


        this.state = {
            color : 'red'
        }
    }


    render(){
        return (
                 <Provider value={this.state.color}>
                        <h1>我是父組件</h1>
                        <Son></Son>
                </Provider>
        );
    }
}



class Son extends Person{
    render(){
        return <div>
            <h3>我是子組件</h3>
            <Son1></Son1>
        </div>
    }
}



class Son1 extends Son{
    render(){
        return (
            <Consumer>
                {
                    (color) => <div>
                        <h6 style={{color}}>我是孫子組件-----{color}</h6>
                    </div>
                }
            </Consumer>
        );
        
    }
}



ReactDOM.render(<div>
    <Person></Person>
</div>,document.getElementById('app'))

參考作品出處:
https://segmentfault.com/a/1190000017758300


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM