react 【context在函式元件和class元件中的使用】
前言
在一個典型的 React 應用中,資料是通過 props 屬性自上而下(由父及子)進行傳遞的,但這種做法對於某些型別的屬性而言是極其繁瑣的(例如:地區偏好,UI 主題),這些屬性是應用程式中許多元件都需要的。Context 提供了一種在元件之間共享此類值的方式,而不必顯式地通過元件樹的逐層傳遞 props。
可以訪問的生命週期
class元件
在shouldComponentUpdate之後訪問,constructor和getDeriverdStateFromProps中無法訪問到
函式元件
函式元件通過hook訪問
更新規則
當 Provider 的 value
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
//建立一個contextView Codeconst 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> ); };