<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      React中useContext的基本使用和原理解析

      React 中 useContext 的使用方法

      在 React 中,useContext 是一個內置的 Hook,用于在函數組件中輕松訪問 Context(全局公共狀態),避免了手動逐層傳遞 props 的復雜性。它依賴于 Context API,通過 Provider 提供數據,后代組件通過 useContext 消費數據。以下是詳細的使用方法和步驟,基于 React 官方指南和實踐經驗。

      1. 創建 Context 對象

      首先需要使用 React.createContext 創建一個 Context 對象。這個對象包含 ProviderConsumer 組件,但 useContext 簡化了消費過程。

      import React from 'react';
      // 創建Context,可設置默認值(可選)
      const MyContext = React.createContext(defaultValue);
      
      • defaultValue 是當組件上方無 Provider 時的回退值,通常設為 null 或初始狀態。

      2. 使用 Provider 提供數據

      在父組件中,用 <Context.Provider> 包裹子組件,并通過 value 屬性傳遞數據。Provider 必須位于調用 useContext 的組件之上。

      import React from 'react';
      import ChildComponent from './ChildComponent';
      import MyContext from './MyContext';
      
      function ParentComponent() {
        const sharedData = { theme: 'dark', user: 'Alice' }; // 共享數據
        return (
          <MyContext.Provider value={sharedData}>
            <ChildComponent /> {/* 后代組件可訪問sharedData */}
          </MyContext.Provider>
        );
      }
      
      • ?注意?:Provider 的 value 變化時,所有消費該 Context 的組件會自動重新渲染??。

      3. 在后代組件中使用 useContext 消費數據

      在后代組件中,導入 Context 對象并調用 useContext,直接獲取 Provider 提供的 value

      import React, { useContext } from 'react';
      import MyContext from './MyContext'; // 導入父組件中的Context
      
      function ChildComponent() {
        const publicData = useContext(MyContext); // 調用useContext獲取數據
        return (
          <div>
            <p>當前主題: {publicData.theme}</p>
            {/* 示例:渲染圖片或其他UI */}
            <img src="image-path" alt="示例" style={{ width: '50px', marginLeft: '10px' }} />
          </div>
        );
      }
      
      • ?關鍵點?:
        • useContext(MyContext) 返回最近的 Provider 的 value;若無 Provider,則返回 defaultValue
        • 代碼簡潔,無需嵌套 <Context.Consumer>
        • Context 變化時,React 會觸發組件重新渲染,確保數據最新??。

      4. 完整代碼示例

      整合以上步驟,一個簡單應用:

      // 文件: Context.js
      import React from 'react';
      export const ThemeContext = React.createContext({ theme: 'light' });
      
      // 文件: App.js (父組件)
      import React from 'react';
      import { ThemeContext } from './Context';
      import Child from './Child';
      
      function App() {
        return (
          <ThemeContext.Provider value={{ theme: 'dark' }}>
            <Child />
          </ThemeContext.Provider>
        );
      }
      
      // 文件: Child.js (后代組件)
      import React, { useContext } from 'react';
      import { ThemeContext } from './Context';
      
      function Child() {
        const { theme } = useContext(ThemeContext);
        return <div>當前主題: {theme}</div>; // 輸出: 當前主題: dark
      }
      

      在類組建中,useContext 的使用方法

      在類組件中使用 Context 有兩種方式:

      1. 使用 static contextType 屬性(只能訂閱單一 Context)
      2. 使用 Context.Consumer(可訂閱多個 Context)

      而在函數組件中,我們使用 useContext 鉤子(可訂閱多個 Context)。

      下面我將詳細說明類組件中使用 Context 的方法,并對比函數組件中的使用差異。

      1、使用 static contextType(單一 Context 訂閱)

      步驟:

      • 創建 Context:const MyContext = React.createContext(defaultValue);
      • 在類組件中通過 static contextType = MyContext; 指定要訂閱的 Context
      • 通過 this.context 訪問 Context 的值

      示例代碼

      import React from 'react';
      
      // 創建Context
      const ThemeContext = React.createContext('light');
      
      class MyClassComponent extends React.Component {
        static contextType = ThemeContext; // 關鍵:靜態屬性賦值
      
        render() {
          const theme = this.context; // 通過this.context訪問
          return <div>當前主題: {theme}</div>;
        }
      }
      
      // 在父組件中提供Context
      function App() {
        return (
          <ThemeContext.Provider value="dark">
            <MyClassComponent />
          </ThemeContext.Provider>
        );
      }
      

      2、使用 Context.Consumer(支持多個 Context)

      步驟:

      • 在類組件的 render 方法中,使用 <MyContext.Consumer> 組件包裹
      • 內部使用函數作為子元素(render prop 模式)

      示例代碼:

      import React from 'react';
      
      // 創建兩個Context
      const ThemeContext = React.createContext('light');
      const UserContext = React.createContext('Guest');
      
      class MyClassComponent extends React.Component {
        render() {
          return (
            // 消費多個Context
            <ThemeContext.Consumer>
              {theme => (
                <UserContext.Consumer>
                  {user => (
                    <div>
                      主題: {theme}, 用戶: {user}
                    </div>
                  )}
                </UserContext.Consumer>
              )}
            </ThemeContext.Consumer>
          );
        }
      }
      
      // 在父組件中提供多個Context
      function App() {
        return (
          <ThemeContext.Provider value="dark">
            <UserContext.Provider value="Alice">
              <MyClassComponent />
            </UserContext.Provider>
          </ThemeContext.Provider>
        );
      }
      

      3、類組件與函數組件使用 Context 的主要區別

      特性 類組件 函數組件
      訂閱方式 1. static contextType + this.context(單一)2. Context.Consumer(支持多個) useContext 鉤子(支持多個)
      多個 Context 使用 使用 Context.Consumer 嵌套較深 直接多次調用 useContext,簡潔清晰
      代碼簡潔性 相對冗長,尤其是多個 Context 時 非常簡潔
      組件類型限制 static contextType 僅適用于類組件(引用[1]) useContext 僅適用于函數組件
      動態更新 當 Context 更新時,組件都會重新渲染 同樣重新渲染,但可通過 React.memo 優化

      4、useContext 實現原理詳解

      useContext 的實現原理基于 React 的 上下文機制(Context) 和 ?訂閱-發布模式?,主要涉及三個核心環節:

      1. Context 對象的內部結構

      每個通過 createContext() 創建的 Context 對象包含以下關鍵屬性:

      const MyContext = React.createContext(defaultValue);
      // 內部結構:
      {
        _currentValue: defaultValue,  // 當前值存儲
        _threaded: true,             // 標識當前渲染線程
        Provider: { ... },           // Provider 組件
        Consumer: { ... },           // Consumer 組件
        _currentRenderer: null,      // 當前渲染器
        _globalName: null,           // 全局名稱
        _subscribe: function() { ... } // 訂閱函數
      }
      

      核心是 _currentValue (存儲當前值) 和 _subscribe (管理訂閱者鏈表)

      2. 值讀取與訂閱機制

      當調用 useContext(MyContext) 時:

      function useContext(Context) {
        // 1. 從 Context._currentValue 讀取當前值
        const value = readContext(Context); 
        
        // 2. 將當前組件添加到訂閱鏈表
        subscribeToContext(Context, currentlyRenderingFiber);
        
        return value; // 返回上下文值
      }
      

      currentlyRenderingFiber 是 React 內部的一個?全局變量?,用于指向當前正在執行的函數組件所對應的 ?Fiber 節點?。它的主要作用是在函數組件渲染過程中為 Hooks 提供訪問當前組件狀態的橋梁。

      具體過程:

      1. ?讀取值?:直接訪問 Context._currentValue 獲取最新值
      2. ?建立訂閱?:將當前函數組件對應的 Fiber 節點添加到 Context 的訂閱者鏈表
        • 通過 currentlyRenderingFiber.dependencies 鏈表維護訂閱關系
        • 每個依賴項包含 context 指針和訂閱狀態

      3. 更新觸發流程

      當 Provider 的值更新時:

      <MyContext.Provider value={newValue}>
      // 1. 更新 Context._currentValue = newValue
      // 2. 遍歷訂閱者鏈表 (Context._subscribe)
      // 3. 標記所有訂閱組件的 Fiber 節點為需要更新
      // 4. 觸發重新渲染
      

      關鍵點:

      • ?批量更新?:React 會合并多個 Context 更新,避免頻繁渲染
      • ?精準更新?:只更新訂閱該 Context 的組件(通過 Fiber 依賴鏈)
      • ?默認值處理?:無 Provider 時返回 createContext(defaultValue) 的默認值
      posted @ 2025-11-03 21:46  老李說技術  閱讀(24)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品无人区卡一卡二卡三乱码| 亚洲码国产精品高潮在线| 福利网午夜视频一区二区| 国产精品亚洲中文字幕| 2021国产成人精品久久| 欧美牲交40_50a欧美牲交aⅴ| 国产精品爱久久久久久久电影| 福利一区二区1000| 少妇放荡的呻吟干柴烈火动漫| 国产在线精品一区二区三区不卡| 日日碰狠狠添天天爽五月婷| 久久99精品国产99久久6男男| 国产真人无遮挡免费视频| 无遮无挡爽爽免费视频| 保德县| 日韩免费美熟女中文av| 瑞金市| 国产久免费热视频在线观看| 亚洲中文久久久精品无码| 一区二区三区av在线观看| 激情综合网激情综合网激情| 国产精品成| 一区二区三区日本久久九| 国产成人精品中文字幕| 国产亚洲精品AA片在线播放天 | 精品久久精品午夜精品久久| 国产成人AV大片大片在线播放| 国产精品不卡区一区二| 人妻少妇精品视频二区| 久久精品无码免费不卡| 国产一区二区不卡在线| 日本一区二区不卡精品| 人妻无码久久久久久久久久久 | 国自产拍偷拍精品啪啪一区二区| 视频一区视频二区视频三区| 日本成熟少妇激情视频免费看| 额济纳旗| 午夜精品区| 日韩丝袜人妻中文字幕| 国产黄色一区二区三区四区| 91高清免费国产自产拍|