react中的useContext--為什么使用(一)

React 的數據傳遞流程

在 React 中,數據傳遞通常是自上而下的,也就是父組件把數據通過 props 傳遞給子組件,子組件無法直接修改父組件的數據。
在這里插入圖片描述

例子:父組件向子組件傳遞數據
const Parent = () => {const user = { name: "John", age: 24 };return <Child user={user} />;
};const Child = ({ user }) => {return (<div><h2>姓名: {user.name}</h2><h2>年齡: {user.age}</h2></div>);
};

問題不大,看起來很簡單,對吧?


子組件傳遞數據的“噩夢”

但如果子組件需要修改父組件的數據,就必須通過回調函數,讓子組件把新的數據“反向”傳回父組件,讓父組件更新數據。

例子:子組件修改父組件數據
const Parent = () => {const [user, setUser] = useState({ name: "John", age: 24 });// 讓子組件調用這個方法來修改 userconst updateUser = (newName) => {setUser({ ...user, name: newName });};return <Child user={user} updateUser={updateUser} />;
};const Child = ({ user, updateUser }) => {return (<div><h2>姓名: {user.name}</h2><button onClick={() => updateUser("Alice")}>改名為 Alice</button></div>);
};

這樣,點擊按鈕后,John 就會變成 Alice,但這還不算太糟糕。

真正的問題是:如果有很多層嵌套怎么辦?


多層嵌套時的“數據傳遞地獄”

如果 Child 不是直接在 Parent 里面,而是嵌套了好幾層,每一層都要手動傳 props,就會變得非常痛苦。

數據傳遞“地獄”示例
const Parent = () => {const [user, setUser] = useState({ name: "John", age: 24 });const updateUser = (newName) => {setUser({ ...user, name: newName });};return <Level1 user={user} updateUser={updateUser} />;
};// 一層又一層地傳遞 props...
const Level1 = ({ user, updateUser }) => <Level2 user={user} updateUser={updateUser} />;
const Level2 = ({ user, updateUser }) => <Level3 user={user} updateUser={updateUser} />;
const Level3 = ({ user, updateUser }) => <Level4 user={user} updateUser={updateUser} />;
const Level4 = ({ user, updateUser }) => (<div><h2>姓名: {user.name}</h2><button onClick={() => updateUser("Alice")}>改名為 Alice</button></div>
);

問題:

  • 你要在 每一層組件 都寫 props 傳遞,代碼變得冗長且難以維護。
  • 組件越多,數據傳遞越混亂,很容易出錯。
  • 這個問題被稱為 “Props Drilling”(屬性挖掘),就像挖礦一樣,數據要一層一層往下挖。

如何解決?—— useContext 來救場!

React 提供了 useContext,它就像一個全局數據倉庫,可以讓任何組件直接訪問數據,而不需要層層 props 傳遞。

步驟 1:創建 Context
import { createContext, useState } from "react";// 1. 創建 Context
const UserContext = createContext();// 2. 創建 Provider 組件
const UserProvider = ({ children }) => {const [user, setUser] = useState({ name: "John", age: 24 });const updateUser = (newName) => {setUser({ ...user, name: newName });};return (<UserContext.Provider value={{ user, updateUser }}>{children}  {/* 這里的 children 讓所有子組件都能訪問這個 Context */}</UserContext.Provider>);
};export { UserContext, UserProvider };

步驟 2:子組件直接用 useContext 讀取數據
import { useContext } from "react";
import { UserContext } from "./UserContext";const UserProfile = () => {const { user, updateUser } = useContext(UserContext);return (<div><h2>姓名: {user.name}</h2><button onClick={() => updateUser("Alice")}>改名為 Alice</button></div>);
};export default UserProfile;

步驟 3:在 App.js 里包裹 Provider
import React from "react";
import { UserProvider } from "./UserContext";
import UserProfile from "./UserProfile";const App = () => {return (<UserProvider><UserProfile /></UserProvider>);
};export default App;

為什么 useContext 很強大?

  1. 避免了“數據傳遞地獄”:不需要層層 props 傳遞,所有組件都能直接訪問數據。
  2. 代碼更清晰:不管組件嵌套多少層,都能方便地讀取和更新數據。
  3. 性能更好:不會因為 props 變化導致所有中間組件都重新渲染。

總結

  1. 傳統數據傳遞方式(props

    • 適合小型項目,數據傳遞簡單時使用。
    • 但是當層級變深時,props drilling 讓代碼變得難以維護。
  2. useContext 方式

    • 適合共享狀態的場景,比如用戶信息、主題設置、語言切換等。
    • 讓所有組件都能直接訪問數據,避免 props 層層傳遞。
  3. 最佳實踐

    • 如果數據只在父子組件之間傳遞,用 props 即可。
    • 如果數據需要被多個組件共享,使用 useContext 來簡化代碼。

🚀 現在,你可以擺脫“數據傳遞地獄”,用 useContext 讓 React 代碼更清爽!

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

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

相關文章

如何使用 LLM 生成的術語自動在搜索應用程序上構建 autocomplete 功能

作者&#xff1a;來自 Elastic Michael Supangkat 了解如何在 Elastic Cloud 中&#xff0c;通過使用 LLM 生成的詞匯&#xff0c;為搜索應用增強自動補全功能&#xff0c;實現更智能、更動態的搜索建議。 自動補全是搜索應用中的一項關鍵功能&#xff0c;它通過在用戶輸入時實…

MAVEN手動配置(阿里云)全教程

介于網上各種各樣的MAVEN配置過程中方法大致相同卻細節參差不齊&#xff0c;我總結了我遇見的一些問題&#xff0c;來完全的解決MAVEN手動配置的全過程&#xff0c;以及分享解決小毛病的經驗。 所需材料&#xff1a; MAVEN3.9.9&#xff08;下載適合自己的版本即可&#xff09…

DeepSeek 3FS:端到端無緩存的存儲新范式

在 2025 年 2 月 28 日&#xff0c;DeepSeek 正式開源了其高性能分布式文件系統 3FS【1】&#xff0c;作為其開源周的壓軸項目&#xff0c;3FS 一經發布便引發了技術圈的熱烈討論。它不僅繼承了分布式存儲的經典設計&#xff0c;還通過極簡卻高效的架構&#xff0c;展現了存儲技…

HarmonyOS:如何將圖片轉為PixelMap并進行圖片緩存策略

前言&#xff1a;在HarmonyOS項目開發中&#xff0c;我們使用Ark-Ts語言開發項目。我們有個功能是拍照&#xff0c;除了正常顯示出來&#xff0c;并且上傳服務器。我在開發過程中&#xff0c;遇到的問題是&#xff0c;如果離開這個頁面再回到當前頁面仍要顯示圖片&#xff0c;那…

2025.3.9機器學習筆記:文獻閱讀

2025.3.9周報 一、文獻閱讀題目信息摘要Abstract創新點網絡架構實驗結論不足以及展望 一、文獻閱讀 題目信息 題目&#xff1a; Time-series generative adversarial networks for flood forecasting期刊&#xff1a; Journal of Hydrology作者&#xff1a; Peiyao Weng, Yu …

linux固定IP并解決虛擬機無法ping其他電腦問題

linux固定IP并解決虛擬機無法ping其他電腦問題 1.找到網卡文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 2.編輯文件信息 BOOTPROTO 這個dhcp改為static#添加以下內容IPADDR<你的IP地址>NETMASK<子網掩碼>&#xff0c;例如255.255.255.0。GATEWAY<網…

Spring實戰spring-ai運行

目錄 1. 配置 2 .搭建項目 3. 查看對應依賴 3.1 OpenAI 依賴 3.2 配置 OpenAI API 密鑰 application.properties application.yml 4. openai實戰 5. 運行和測試 6. 高級配置 示例&#xff1a;配置模型和參數 解釋&#xff1a; 7. 處理異常和錯誤 示例&#xff1a;…

docker:配置 Docker 鏡像加速器

1 鏡像加速器介紹 默認情況下&#xff0c;將來從docker hub&#xff08;https://hub.docker.com/&#xff09;上下載docker鏡像&#xff0c;太慢。一般都會配置鏡像加速器&#xff1a; USTC&#xff1a;中科大鏡像加速器&#xff08;https://docker.mirrors.ustc.edu.cn&…

[內網安全] Windows 本地認證 — NTLM 哈希和 LM 哈希

關注這個專欄的其他相關筆記&#xff1a;[內網安全] 內網滲透 - 學習手冊-CSDN博客 0x01&#xff1a;SAM 文件 & Windows 本地認證流程 0x0101&#xff1a;SAM 文件簡介 Windows 本地賬戶的登錄密碼是存儲在系統本地的 SAM 文件中的&#xff0c;在登錄 Windows 的時候&am…

算法-圖-dijkstra 最短路徑

理論知識 dijkstra三部曲 樸素版dijkstra 模擬過程 堆優化版dijksra 經典模版例題 Dijkstra求最短路 I 參加科學大會&#xff08;第六期模擬筆試&#xff09;--模版題 網絡延遲 ref 理論知識 最短路是圖論中的經典問題即&#xff1a;給出一個有向圖&#xff0c;一…

Qt添加MySql數據庫驅動

文章目錄 一. 安裝MySql二.編譯mysql動態鏈接庫 Qt版本&#xff1a;5.14.2 MySql版本&#xff1a;8.0.41 一. 安裝MySql 參考這里進行安裝&#xff1a;https://blog.csdn.net/qq_30150579/article/details/146042922 將mysql安裝目錄里的bin&#xff0c;include和lib拷貝出來…

淺論數據庫聚合:合理使用LambdaQueryWrapper和XML

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、數據庫聚合替代內存計算&#xff08;關鍵優化&#xff09;二、批量處理優化四、區域特殊處理解耦五、防御性編程增強 前言 技術認知點&#xff1a;使用 XM…

Ubuntu 22.04安裝NVIDIA A30顯卡驅動

一、安裝前準備 1.禁用Nouveau驅動 Ubuntu默認使用開源Nouveau驅動&#xff0c;需要手動禁用&#xff1a; vim /etc/modprobe.d/blacklist-nouveau.conf # 添加以下內容&#xff1a; blacklist nouveau options nouveau modeset0 # 更新內核并重啟&#xff1a; update-initr…

Docker Desktop 4.38 安裝與配置全流程指南(Windows平臺)

一、軟件定位與特性 Docker Desktop 是容器化應用開發與部署的一體化工具&#xff0c;支持在本地環境創建、管理和運行Docker容器。4.38版本新增GPU加速支持、WSL 2性能優化和Kubernetes 1.28集群管理功能&#xff0c;適用于微服務開發、CI/CD流水線搭建等場景。 二、安裝環境…

音視頻入門基礎:RTP專題(15)——FFmpeg源碼中,獲取RTP的視頻信息的實現

一、引言 通過FFmpeg命令可以獲取到SDP文件描述的RTP流的視頻壓縮編碼格式、色彩格式&#xff08;像素格式&#xff09;、分辨率、幀率信息&#xff1a; ffmpeg -protocol_whitelist "file,rtp,udp" -i XXX.sdp 本文以H.264為例講述FFmpeg到底是從哪個地方獲取到這…

深度學習---卷積神經網絡

一、卷積尺寸計算公式 二、池化 池化分為最大池化和平均池化 最常用的就是最大池化&#xff0c;可以認為最大池化不需要引入計算&#xff0c;而平均池化需要引出計算&#xff08;計算平均數&#xff09; 每種池化還分為Pooling和AdaptiveAvgPool Pooling(2)就是每2*2個格子…

netty中Future和ChannelHandler

netty中的Future&#xff0c;繼承自 jdk中的Future&#xff0c;&#xff0c; jdk中的Future&#xff0c;很垃圾&#xff0c;只能同步阻塞獲取結果&#xff0c;&#xff0c;&#xff0c; netty中的Future進行了升級&#xff0c;&#xff0c;可以addListener()異步獲取結果&…

java 初學知識點總結

自己總結著玩 1.基本框架 public class HelloWorld{ public static void main(String[] args){ }//類名用大寫字母開頭 } 2.輸入&#xff1a; (1)Scanner:可讀取各種類型&#xff0c;字符串相當于cin>>; Scanner anew Scanner(System.in); Scan…

質量屬性場景描述

為了精確描述軟件系統的質量屬性&#xff0c;通常采用質量屬性場景&#xff08;Quality Attribute Scenario&#xff09;作為描述質量屬性的手段。質量屬性場景是一個具體的質量屬性需求&#xff0c;使利益相關者與系統的交互的簡短陳述。 質量屬性場景是一種用于描述系統如何…

數據可攜帶權的多重價值與實踐思考

文章目錄 前言一、數據可攜帶權的提出與立法二、數據可攜帶權的多重價值1、推動數據要素市場化配置2、促進市場競爭與創新3、強化個人數據權益 三、數據可攜帶權的實踐挑戰1、數據安全與隱私保護面臨風險2、接口差異導致數據遷移成本高昂3、可攜帶的數據范圍尚存爭議 數據可攜帶…