react 【context在函數組件和class組件中的使用】


前言

  在一個典型的 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>
    );
  }
}
View Code

  函組件

const Son = (props: any) => {
  const context: any = useContext(MyContext); //通過hook useContext指定消費Context,
  console.log("son", context); //
  return (
    <div>
     {/* 其他輸出 */}
    </div>
  );
};

 

 

 

 


免責聲明!

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



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