【React】React18 Hooks 之 useContext

目錄

  • useContext
    • 1、Provider和 useContext
    • 2、Provider 和Consumer
    • 3、Provider 嵌套
    • 4、React.createContext提供的Provider和class的contextType屬性
    • 5、讀、寫Context
      • (1)父組件修改Context
      • (2)子組件修改Context
  • 好書推薦

在這里插入圖片描述

useContext官方地址
使用 Context 深度傳遞數據

通常,您會通過 props 將信息從父組件傳遞到子組件。但是,如果您必須通過中間的許多組件傳遞信息,或者應用中的許多組件都需要相同的信息,則傳遞 props 會變得冗長且不方便。Context允許父組件向其下方樹中的任何組件(無論深度如何)提供一些信息,而無需通過 props 明確傳遞

簡單來說使用Context可以實現跨組件層級傳遞數據,不用層層傳遞數據。本文介紹三種Context的使用方式。

  • 函數組件:React.createContext提供的ProvideruseContext鉤子
  • React.createContext提供的ProviderConsumer
  • Provider嵌套
  • Class組件:React.createContext提供的ProviderclasscontextType屬性
  • 讀、寫Context

useContext

useContext是一個 React Hook,可讓您從組件讀取和訂閱上下文。

用法:

const value = useContext(SomeContext)

參數的含義:
SomeContext:使用createContext創建的上下文。上下文本身并不包含信息,它只代表您可以提供或從組件中讀取的信息類型。
返回值的含義:
value:useContext返回調用組件的上下文值,傳遞給最接近的SomeContext的值

1、Provider和 useContext

新建個context.js,導出createContext()的返回值

import { createContext } from "react";
export default createContext();

App.js,導入上面寫的context,并使用context提供的Provider組件進行包裹,圈定局部的全局作用域,傳值后可以提供給子組件進行消費。當 Provider 的 value 值發生變化時,它內部的所有消費組件都會重新渲染。

import Context from "./context";
import Test from "./Test"
function App() {const value = "app 中的數據"return (<><Context.Provider value={value}><div className="Appy" ><Test /></div></Context.Provider></>);
}export default App;

新建個Test.js,

import Context from "./context"
import MyComponent from "./MyComponent"
const Test1 = () => {return <><MyComponent/><div></div></>
}
export default Test1

新建個MyComponent.js,使用useContext鉤子接收Context提供的參數

import Context from "./context"
import { useContext } from "react"
const MyComponent = ()=>{const value = useContext(Context)return <><div>value:{value}</div></>
}
export default MyComponent

可以看到頁面中顯示如下:
在這里插入圖片描述
使用Components分析如下:

在這里插入圖片描述

2、Provider 和Consumer

上面的MyComponent.js 文件,我們可以使用Context.Consumer組件接收數據。在MyComponent組件中,導入context,使用其提供的Consumer組件來訂閱Context的變更,需要一個函數作為子元素,函數的第一個形參便是Provider組件提供的value值。如下:

import Context from "./context"
import { useContext } from "react"
const MyComponent = ()=>{const value = useContext(Context)return <><Context.Consumer>{value=><div>value1:{value}</div>}</Context.Consumer></>
}
export default MyComponent

3、Provider 嵌套

新建context.js,創建ThemeContext,AuthContext,然后再分別創建創建 ThemeContext 、AuthContext 的 Provider 組件,Provider 組件主要提供方法。


// context.js
import React, { createContext, useState, useContext } from 'react';// 創建 ThemeContext
const ThemeContext = createContext();// 創建 ThemeContext 的 Provider 組件
const ThemeProvider = ({ children }) => {const [theme, setTheme] = useState('light'); // 假設初始主題是 'light'// 可以通過函數來切換主題const toggleTheme = () => {setTheme(theme === 'light' ? 'dark' : 'light');};return (<ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>);
};// 創建 AuthContext
const AuthContext = createContext();// 創建 AuthContext 的 Provider 組件
const AuthProvider = ({ children }) => {const [user, setUser] = useState(null); // 假設初始用戶是 null// 可以通過函數來設置用戶const login = (userData) => {setUser(userData);};const logout = () => {setUser(null);};return (<AuthContext.Provider value={{ user, login, logout }}>{children}</AuthContext.Provider>);
};// 導出 ThemeProvider 和 AuthProvider,以及它們各自的 Context
export { ThemeContext, ThemeProvider, AuthContext, AuthProvider };

App.js,導入ThemeProvider, AuthProvider,層層嵌套。

import React from 'react';
import { ThemeProvider, AuthProvider } from './context.js'; // 導入提供者
import MyComponent from './MyComponent'; // 假設您有一個 MyComponent 組件const App = () => {return (<ThemeProvider ><AuthProvider ><MyComponent /> {/* MyComponent 現在可以訪問 ThemeContext 和 AuthContext */}</AuthProvider></ThemeProvider>);
};export default App;

MyComponent.js,導入ThemeContext, AuthContext ,使用useContext獲取ThemeContext, AuthContext 的Provider組件傳遞的參數。

import React, { useContext } from 'react';
import { ThemeContext, AuthContext } from './context.js'; // 導入 Contextconst MyComponent = () => {console.log(useContext(ThemeContext),'useContext(ThemeContext)')const { theme, toggleTheme } = useContext(ThemeContext);const { user, login, logout } = useContext(AuthContext);console.log(useContext(AuthContext),'useContext(ThemeContext)')// 使用 theme、toggleTheme、user、login 和 logout 做一些事情...return (// ... 組件的 JSX<div><p>當前主題: {theme}</p><button onClick={toggleTheme}>切換主題</button>{user ? (<div><p>已登錄用戶: {user.name}</p><button onClick={logout}>登出</button></div>) : (<button onClick={() => login({ name: 'John Doe' })}>登錄</button>)}</div>);
};export default MyComponent;

頁面如下:
在這里插入圖片描述

4、React.createContext提供的Provider和class的contextType屬性

static contextType 是一種在類組件中直接訪問 Context 值的方式,而不必明確地傳遞一個 <Context.Consumer> 組件。static contextType 應該被定義在類組件的外部,而不是在 render 方法內部或組件的類體內部。

掛載在 class 上的 contextType 屬性會被重賦值為一個由React.createContext() 創建的 Context 對象。這能讓你使用 this.context 來消費最近 Context 上的那個值。你可以在任何生命周期中訪問到它,包括 render 函數中。
使用static關鍵字添加靜態屬性,和直接在class添加屬性效果一致,最終都會添加到類上,而不是類的實例上

import React, { Component } from "react";
import context from "./context";
class Test1 extends Component {static contextType = context;render() {console.log(Test1.contextType,'contextType');console.log(this.context,'context');const value = this.context;return <div>第三種使用Context方式獲取的值:{JSON.stringify(value)}</div>;}
}// Test1.contextType = context; //此處與寫static關鍵字作用一致
export default Test1;

可以看到打印的Test1.contextTypeReact.createContext() 創建的 Context 對象,打印this.context為最近的 Context 上的值
在這里插入圖片描述

5、讀、寫Context

(1)父組件修改Context

App.js中,更改Context數據,調用組件中的onChange方法。Provider的value不再傳入一個簡單結構的對象,而是將useState的返回值作為新對象的key/value,子組件便能調用App的setStore函數進行更新

import Context from "./context";
import Test from "./Test1" 
import { useState } from "react"
function App() {const value = "app 中的數據"const [store, setStore] = useState(value);const onChange = ()=>{setStore("app 數據 change")}return (<><Context.Provider value={{store, setStore}}><div className="Appy" ><Test /><button onClick={onChange}>按鈕</button></div></Context.Provider></>);
}export default App;

Test.js中,使用useContext接收Context數據。點擊父組件中的按鈕,數據從 app 中的數據變為app 數據 change

import Context from "./context"
import { useContext } from "react"
const Test1 = () => {const value = useContext(Context)console.log(value,'test1組件接收到的')return <>{value.store}<div></div></>
}
export default Test1

(2)子組件修改Context

這里更改子組件的代碼,新增一個button按鈕,使用context接收過來的setStore函數,修改Context數據。點擊button之后,數據由app 中的數據變為子組件修改Context成功。效果與在父組件中修改Context數據一樣。

import Context from "./context"
import { useContext } from "react"
// import MyComponent from "./MyComponent"
const Test1 = () => {const context = useContext(Context)return <>{value.store}<button onClick={()=>context.setStore("子組件修改Context成功")}>子組件button</button></>
}
export default Test1

好書推薦

《Rust Web開發》

如果你厭倦了緩慢、占用大量資源且不穩定的模板化Web開發工具,Rust就是你的解決方案。Rust服務提供了穩定的安全保證、非凡的開發經驗,以及能夠自動防止常見錯誤的編譯器。

《Rust Web開發》教你使用Rust以及重要的Rust庫(如異步運行時的Tokio、用于Web服務器和API的Warp,以及運行外部HTTP請求的Reqwest)來創建服務端的Web應用。《Rust Web開發》包含大量的代碼示例以及專業的提示,以幫助你創建項目和組織代碼。隨著學習的深入,你將創建一個完整的Q&A Web服務并逐章迭代你的代碼,就像參與了真實的項目開發一樣。

這不是一本參考書,而是一本工作手冊。正在構建的應用程序在設計上做出了一些妥協,以便在適當的時候解釋概念。需要閱讀整本書的內容才能最終將應用程序部署到生產環境中。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43578.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43578.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43578.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

NPDP有什么價值?究竟值不值得去考?

NPDP其實就是產品經理國際資格認證&#xff0c;是美國產品開發管理協會發起的&#xff0c;集理論、方法和實踐一體&#xff0c;在新產品開發方面有一個很全面的知識體系。是國際公認的新產品開發專業認證&#xff0c;具有權威性。 NPDP能夠很好地幫你在做新產品的道路上少走彎…

【已解決】騰訊云安裝了redis,但是本地訪問不到,連接不上

匯總了我踩過的所有問題。 查看配置文件redis.conf 1、把bind 127.0.0.1給注釋掉&#xff08;前面加個#就是&#xff09;或者改成bind 0.0.0.0&#xff0c;因為剛下載時它是默認只讓本地訪問。&#xff08;linux查找文檔里的內容可以輸入/后面加需要匹配的內容&#xff0c;然后…

Perl 語言開發(七):哈希和關聯數組

目錄 1. 哈希與關聯數組的概述 2. 哈希的基本操作 2.1 創建哈希 2.2 訪問哈希值 2.3 添加和修改哈希值 2.4 刪除哈希值 2.5 檢查哈希中是否存在某個鍵 3. 迭代哈希 3.1 使用 keys 和 values 3.2 使用 each 4. 復雜數據結構中的哈希 4.1 哈希的數組 4.2 哈希的哈希…

clickhouse-jdbc-bridge rce

clickhouse-jdbc-bridge 是什么 JDBC bridge for ClickHouse. It acts as a stateless proxy passing queries from ClickHouse to external datasources. With this extension, you can run distributed query on ClickHouse across multiple datasources in real time, whic…

Java基礎-組件及事件處理(上)

(創作不易&#xff0c;感謝有你&#xff0c;你的支持&#xff0c;就是我前行的最大動力&#xff0c;如果看完對你有幫助&#xff0c;請留下您的足跡&#xff09; 目錄 Swing 概述 MVC 架構 Swing 特點 控件 SWING UI 元素 JFrame SWING 容器 說明 常用方法 示例&a…

服務器信息獲取工具

功能介紹 SSH連接到遠程服務器&#xff1a; 用戶可以輸入目標服務器的IP地址、用戶名、密碼以及SSH端口&#xff08;默認22&#xff09;。 工具會嘗試連接到遠程服務器&#xff0c;并在連接失敗時顯示錯誤信息。 運行命令并返回輸出&#xff1a; 工具可以在遠程服務器上運…

python (必看)10個提升接口自動化編寫效率的腳本!

親愛的開發者們&#xff0c;&#x1f44b; 在快速迭代的軟件開發周期中&#xff0c;接口自動化測試扮演著至關重要的角色。今天&#xff0c;我們將分享10個實用的Python小腳本&#xff0c;它們能夠顯著提升你編寫接口自動化測試的效率。無論是初學者還是資深工程師&#xff0c;…

某音商品詳情數據實時API接入

在抖音平臺上&#xff0c;商品詳情數據接口&#xff08;通常被提及為“item get”或”item_get_app“API&#xff09;并不是直接對公眾或第三方開發者開放的。抖音的API和接口主要用于其內部系統、合作伙伴以及通過其官方渠道&#xff08;如抖音小店、抖音開放平臺等&#xff0…

算法體系-26 第二十六節:第26節:單調棧結構 (5節)

一 單調棧知識講解 1.1描述 一個數組里面想的到每個位置與他最近的左邊和右邊比他小的最近的信息 1.2 分析 通過單調棧的特點&#xff0c;for遍歷數組中的每個數&#xff0c;當前數來的時候對比單調棧中的數進行每個數的左右判斷完滿足條件的進行更新到當前i種的 int[][] re…

WPScan漏洞掃描工具的介紹及使用

目錄 1. 介紹2. 常用參數 1. 介紹 WPScan是Kali Linux默認自帶的一款漏洞掃描工具&#xff0c;它采用Ruby編寫&#xff0c;能夠掃描WordPress網站中的多種安全漏洞&#xff0c;其中包括WordPress本身的漏洞、插件漏洞和主題漏洞&#xff0c;最新版本WPScan的數據庫中包含超過18…

采用3種稀疏降噪模型對心電信號進行降噪(Matlab R2021B)

心電信號采集自病人體表&#xff0c;是一種無創性的檢測手段。因此&#xff0c;心電信號采集過程中&#xff0c;本身也已經包含了機體內部其他生命活動帶來的噪聲。同時&#xff0c;由于采集設備和環境中存在電流的變化&#xff0c;產生電磁發射等物理現象&#xff0c;會對心電…

學習測試7-ADB的使用

ADB是什么&#xff1f; ADB&#xff0c;即 Android Debug Bridge&#xff08;安卓調試橋&#xff09; 是一種允許模擬器或已連接的 Android 設備進行通信的命令行工具&#xff0c;它可為各種設備操作提供便利&#xff0c;如安裝和調試應用&#xff0c;并提供對 Unix shell&…

最新全國1-5級標準河流水系矢量數據

2023最新全國一級&#xff5e;五級標準河流水系 shp 矢量數據 2023最新全國一級&#xff5e;五級標準河流水系 shp 矢量數據 Arcgis 五級河流水系全國合集和按省區分 坐標系&#xff1a;wgs84 更新年份&#xff1a;2023年 包含20230SM提取全國超詳細水體 Arcgis 矢量數據&a…

AcWing 849. Dijkstra求最短路 I

給定一個 n 個點 m 條邊的有向圖&#xff0c;圖中可能存在重邊和自環&#xff0c;所有邊權均為正值。 請你求出 11 號點到 n 號點的最短距離&#xff0c;如果無法從 1 號點走到 n 號點&#xff0c;則輸出 ?1。 輸入格式 第一行包含整數 n 和 m。 接下來 m 行每行包含三個整…

Python從Excel表中查找指定數據填入新表

#讀取xls文件中的數據 import xlrd file "原表.xls" wb xlrd.open_workbook(file) #讀取工作簿 ws wb.sheets()[0] #選第一個工作表 data [] for row in range(7, ws.nrows): name ws.cell(row, 1).value.strip() #科室名稱 total1 ws.cell(row, 2…

TIA博途與威綸通觸摸屏無實物仿真調試的具體方法示例

TIA博途與威綸通觸摸屏無實物仿真調試的具體方法示例 準備條件: TIA PORTAL V16 S7-PLCSIM V16 EasyBuilderPro V6.9.1 NetToPLCsim V1.2.5 如有需要,可以在這個鏈接中下載 NetToPLCSim - Browse Files at SourceForge.net538 weekly downloads3 weekly downloads12 weekly d…

QTransform 解析

實例: 以點(100,100) 圍繞點(200,150)旋轉45后的坐標, 采用QTransform 類方法實現移動變換. Test1 采用一個QTransform 對象,通過連續的變換后,發現最后的結果與預先的不一致. 原因: 當trans1.translate(-200., -150.); 后,坐標系的原點變成了-200,-150. 之后trans1.rotat…

LoveDA: 遙感土地覆蓋數據集的領域自適應語義分割

引入了土地覆蓋域自適應語義分割(LoveDA)數據集來推進語義和可轉移學習。LoveDA數據集包含來自三個不同城市的5987張高分辨率圖像和166768個帶注釋的對象。與現有數據集相比&#xff0c;LoveDA數據集包含兩個領域(城市和農村)&#xff0c;這帶來了相當大的挑戰&#xff0c;因為…

華為OD機試題-貪心歌手

題目解析 題目描述&#xff1a; 歌手準備從 A 城去 B 城參加演出 按照合同&#xff0c;他必須在 T 天內趕到。歌手途徑 N 座城市。歌手不能往回走。每兩座城市之間需要的天數都可以提前獲知。歌手在每座城市都可以在路邊賣唱賺錢。經過調研&#xff0c;歌手提前獲知了每座城市…

C# AOP面向切面編程

AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面編程&#xff09;是一種編程范式&#xff0c;旨在將橫切關注點&#xff08;Cross-cutting Concerns&#xff09;從業務邏輯中分離出來。在傳統的面向對象編程中&#xff0c;橫切關注點&#xff08;如日志記錄、…