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
状态共享范围较小,逻辑简单
状态复杂、需要统一管理
需要支持时间旅行调试和状态跟踪
状态变化频繁且依赖复杂
轻量级项目,避免过度工具化
相关推荐
qq. 28040339843 小时前
CSS层叠顺序
前端·css
喝拿铁写前端4 小时前
SmartField AI:让每个字段都找到归属!
前端·算法
猫猫不是喵喵.4 小时前
vue 路由
前端·javascript·vue.js
烛阴4 小时前
JavaScript Import/Export:告别混乱,拥抱模块化!
前端·javascript
bin91535 小时前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例12,TableView16_12 拖拽动画示例
前端·javascript·vue.js·ecmascript·deepseek
GISer_Jing5 小时前
[Html]overflow: auto 失效原因,flex 1却未设置min-height &overflow的几个属性以及应用场景
前端·html
程序员黄同学5 小时前
解释 Webpack 中的模块打包机制,如何配置 Webpack 进行项目构建?
前端·webpack·node.js
拉不动的猪5 小时前
vue自定义“权限控制”指令
前端·javascript·vue.js
再学一点就睡5 小时前
浏览器页面渲染机制深度解析:从构建 DOM 到 transform 高效渲染的底层逻辑
前端·css
拉不动的猪5 小时前
刷刷题48 (setState常规问答)
前端·react.js·面试