首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-06 05:45
  • 3875
  • 10432
juejin.cn

在前不久的一篇文章 React 开发 - 认识Zustand 中,我们了解了通过 Zustand 进行状态管理。这篇文章,我们直接来学习通过 createContext 来进行组件树的状态管理。

React.createContext 是用于创建上下文,方便组件树中共享数据,而不需要通过 props 逐层传递数据。

用法

使用它也是很简单:

  1. 创建上下文 - createContext
  2. 使用 Provider 提供上下文
  3. 使用 useContext 钩子消费上下文
tsx
代码解读
复制代码
// demo.jsx import React, { createContext, useContext } from "react"; import { ChildComponent } from "path/to/ChildComponent.tsx"; // 1. 创建上下文对象 const MyContext = createContext(null); function Demo() { const value = { name: "Jimmy", address: "Canton"}; return ( // 2. 使用 Provider 提供上下文 <MyContext.Provider value={ value }> <ChildComponent /> MyContext.Provider> ); }

上面是父组件,下面我们来编写消费的子组件 ChildComponent,如下:

tsx
代码解读
复制代码
// ChildComponent.tsx function ChildComponent() { // 3. 使用 useContext 钩子来消费上下文值 const value = useContext(MyContext); return ( <div> <p>Name: {value.name}p> <p>Address: {value.address}p> div> ); }

上面我们通过一个简单的案例已经了解了怎么使用它。下面,我们通过一个详细的案例来熟悉它。

案例

假设我们需要在父组件中传递数据给子组件,然后,在子组件的各个地方都能够 dispatch 数据回传到父组件进行处理。

在进入正文之前,我们有必要了解下 React.useReducer 这个钩子函数。

useReducer 是 React 提供的用于管理组件的状态的钩子函数,类似于 useState,但是更加适合处理复杂的状态逻辑。

useReducer 接受三个参数:

  • reducer: 一个函数,用于处理状态更新逻辑。它接受当前状态和一个 action 对象,并且返回新的状态。如下例子中的 shootReducer
  • initialState:初始状态
  • init: 可选,一个函数,用于惰性初始化状态

什么叫做惰性初始化。惰性初始化意味着初始状态的计算会被延迟到组件首次渲染时进行,而不是在定义 useReducer 时立即计算。这种方式可以提高性能,特别是当初始状态的计算比较复杂或者依赖于某些异步的操作时。当传入第三个参数的时候,第二个参数的意义就没那么重要了

嗯~进入正题。我们有下面的父组件👇

tsx
代码解读
复制代码
const noop = () => {} // 接口 action interface IShootAction { type: "updateShootCount" | "updateCountDown" } // 接口 state interface IShootState { shootCount: number; countDown: number; } // 上下文 export const ShootContext = React.createContext({ shootCount:1, countDown: -1, dispatch: noop as React.Dispatch<IShootAction> }); // 更改 state function shootReducer(state: IShootState, action: IShootAction): IShootState { switch (action.type) { case "updateShootCount": state.shootCount = action.shootCount ?? state.shootCount; break; case "updateCountDown": state.countDown = action.countDown ?? state.countDown; break; } return { ...state }; } // 父函数组件 export const ShootView: React.FC = () => { const operate = "paperwork"; // useReducer 钩子 const [ { shootCount, countDown }, dispatch, ] = React.useReducer( // 处理状态更新逻辑的函数 shootReducer, // 初始状态 { shootCount: 3, countDown: -1 }, // 惰性初始化 (state) => { if(operate === "paperwork") { state.shootCount = 5; } else { state.shootCount = 8; } } ); // 接下来,我们就进行上下文的提供了 return ( <ShootContext.Provider value = {{ countDown, shootCount, dispatch, }}> <ChildComponent /> ShootContext.Provider> ); }

我们将一些状态和 dispatch 传递给子组件,接下来,我们在子组件中进行对应的操作👇

tsx
代码解读
复制代码
export interface IChildComponentProps {} export ChildComponent: React.FC<IChildComponentProps> = (props) => { // 子组件中消费上下文 const { countdown, dispatch } = React.useContext(ShootContext); return ( // 直接展示相关的状态 <> <p>CountDown: { countdown }p> {/* 这里我们通过 dispatch 来更改 shootCount */} <button onClick={(dispatch) =>{ if ( // something true happen) { dispatch({ type: "updateCountdown", countDown: 13 }); } }}>Change ShootCountbutton> ); }

当然,上面我们只是局限在页面中进行展示使用 dispatch,我们也可以在组件调用的钩子函数中去使用 dispath 来管理代码。

嗯~ 今天的话题到这里结束,【完】❀

注:本文转载自juejin.cn的Jimmy的文章"https://juejin.cn/post/7444856714337435699"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top