前言
在一個典型的 React 應用中,數據是通過 props 屬性自上而下(由父及子)進行傳遞的,但這種做法對於某些類型的屬性而言是極其繁瑣的(例如:地區偏好,UI 主題),這些屬性是應用程序中許多組件都需要的。Context 提供了一種在組件之間共享此類值的方式,而不必顯式地通過組件樹的逐層傳遞 props。
可以訪問的生命周期
class組件
在shouldComponentUpdate之后訪問,constructor和getDeriverdStateFromProps中無法訪問到
函數組件
函數組件通過hook訪問
更新規則
當 Provider 的 value
值發生變化時,它內部的所有消費組件都會重新渲染。Provider 及其內部 consumer 組件都不受制於 shouldComponentUpdate
函數,因此當 consumer 組件在其祖先組件退出更新的情況下也能更新。
通過新舊值檢測來確定變化,使用了與 Object.is
相同的算法。
涉及api
react.createContext:context函數
<Context.Provider>:組件元素,被包裹的組件可以及其子元素可以通過contextType消費context
Class.contextType:指定消費context,必須要是被<Context.Provider>包裹的元素
Context.Consumer:指定消費context,和Class.contextType作用一致,區別是此方法適用於函數組件。 與Context.Provider不同的是,Context.Provider可以嵌套使用,而Context.Consumer的children必須是一個函數組件
ps:函數組件推薦使用hook useContext,此方法或許在后續版本會被移除.
Context.displayName:定義context在devtools中的別名配合調試工具使用
涉及hook
useContext
案例代碼
class

//創建一個context const MyContext = react.createContext("init"); //祖先組件 const ancestor = () => { return ( <div> <h2>ancestor</h2> <div> <MyContext.Provider value={"context value"}> //包裹子組件 <Son /> </MyContext.Provider> </div> </div> ); }; //子組件 const Son = () => { return ( <div> <h2>son</h2> <div> <Grandson /> //孫組件 </div> </div> ); }; //孫組件 class Grandson extends react.Component { //注入context 在class組件中,必須要為static屬性contextType,設置通過react.createContext()創建的context對象,才能使用this.context,不然this.context的值會為一個{} static contextType = MyContext; componentDidMount() { console.log(this.context); //context value } render() { return ( <div> <h2>grandson</h2> <div> <span>獲取的context值:</span> </div> </div> ); } }
函組件
const Son = (props: any) => { const context: any = useContext(MyContext); //通過hook useContext指定消費Context, console.log("son", context); // return ( <div> {/* 其他輸出 */} </div> ); };