5min学会React中父子或者兄弟组件共享数据!

组件间的数据共享

在前端开发中,组件间的数据传递是一个重要的问题。日常工作中,我们大多会使用 props 进行数组传递。当组件结构较为简单时,这种方式非常直观。然而,当数据需要在深层次的嵌套组件中使用时,我们需要层层传递props,这种方式非常麻烦且容易出错。

在vue3中,可以通过Provide 可以在父组件中声明数据,然后在后代子组件Inject注入即可使用!在React中,我们可以使用useContext实现同样的效果。

什么是 useContext

React 的 useContext 是一个 Hook,用于共享全局状态或父组件的数据。它简化了通过 props 层层传递数据的过程,使得开发者可以在任意子组件中直接访问上下文中的数据。

使用场景

  • 状态共享:如父组件信息、主题配置等(个人喜欢将父组件的数据派发给所有后代组件)。
  • 避免 props drilling:减少不必要的中间层 props 传递。

基本语法

我们通过共享用户信息为例演示其基本语法。

  • 创建上下文对象

一般来说,context可以单独维护在一个文件内。

js 复制代码
// context.tsx

import React, { createContext } from "react";

const MyContext = createContext(Context);

// 导出上下文对象,供父子组件消费
export default MyContext
  • 提供数据

使用 UserContext.Provider 将用户信息共享给子组件。

js 复制代码
// 引入子组件
import Child from "./Child.tsx"
// 引入上下文对象
import MyContext from "./context.tsx"

// 父组件
const Parent = ({ children }) => {
  const [user, setUser] = useState({ name: "xiexiaoxie", age: 18 });

  const updateUser = (newUser) => setUser(newUser);

  return (
    <MyContext.Provider value={{ user, updateUser }}>
       <Child />
    </MyContext.Provider>
  );
};

export default Parent;

使用MyContext.Provider包裹在应用的顶层,所有子组件都能访问 MyContext。value是提供给子组件的值。

  • 子组件消费数据

通过 MyContext 使用上下文中的数据。

js 复制代码
import React, { useContext } from "react";
// 引入上下文对象
import MyContext from "./context.tsx"

const Child = () => {
  // 导出并使用父组件的数据和方法
  const { user, updateUser } = useContext(MyContext);

  const handleChangeName = () => {
    updateUser({ ...user, name: "哈哈哈" });
  };

  return (
    <div>
      <p>用户名:{user.name}</p>
      <p>年龄:{user.age}</p>
      <button onClick={handleChangeName}>修改用户名</button>
    </div>
  );
};

export default Child;

其他语法

createContext 的默认值

在使用 React.createContext 创建上下文时,可以通过参数为上下文设置一个 默认值(defaultValue) 。默认值的作用是 在没有使用对应的 Provider 包裹组件时,消费者组件会使用该默认值。

js 复制代码
const MyContext = React.createContext({ user:"查无此人", updateUser:()=> {} });

多个上下文的嵌套

如果需要同时使用多个上下文,可以将它们嵌套使用。

js 复制代码
const ThemeContext = createContext();
const UserContext = createContext();

const App = () => (
  <ThemeContext.Provider value="dark">
    <UserContext.Provider value={{ name: "Alice" }}>
      <ChildComponent />
    </UserContext.Provider>
  </ThemeContext.Provider>
);

为什么不使用Redux

熟悉Redux的同学一定会问,为什么不使用Redux,这是因为他们的适用的场景和功能范围存在显著差异。

  • 功能范围
特性 useContext Redux
状态管理范围 适用于局部状态共享(如父子组件、主题、用户信息等) 适用于全局状态管理
复杂度 较简单,基于 React 内置 API 较复杂,需要单独安装和配置
状态来源 状态通常存储在某个组件的 useState中 状态存储在单独的全局 Store
调试能力 无专用工具,调试依赖 React DevTools Redux DevTools 提供强大的时间旅行调试
中间件支持 不支持中间件 支持中间件(如 Redux Thunk、Saga)
  • 适用场景
场景 推荐使用 useContext 推荐使用 Redux
状态共享范围较小,逻辑简单 ✅ ❌
状态复杂、需要统一管理 ❌ ✅
需要支持时间旅行调试和状态跟踪 ❌ ✅
状态变化频繁且依赖复杂 ❌ ✅
轻量级项目,避免过度工具化 ✅ ❌
相关推荐
小码哥_常6 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
蜗牛攻城狮8 小时前
微前端四大方案选型对比与最佳实践:qiankun、micro-app、wujie、Module Federation
前端·微前端·qiankun·前端架构·micro-app·wujie
她说可以呀9 小时前
Vue插槽
前端·javascript·vue.js
qq_448011169 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
aixingpan10 小时前
aixingpan.cn API开发文档:前端查询夏令时和时区接口指南
前端·php
2601_9583529010 小时前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
志尊宝11 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing0312 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel12 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放12 小时前
Python基础语法练习题(73)
java·前端·python