iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >基于ReactContext实现一个简单的状态管理的示例代码
  • 546
分享到

基于ReactContext实现一个简单的状态管理的示例代码

2024-04-02 19:04:59 546人浏览 薄情痞子
摘要

目录前言封装一个父组件用来包裹其他子组件子组件如何获取数据呢class Component 方式context.ConsumeruseContext总结参考前言 在大多数情况下,我们

前言

在大多数情况下,我们开发项目都需要一个状态管理,方便我们在全局共享状态库,在React生态里比较流行的几个库

redux、mobx、recoil

但是对于小项目,我们完全可以自己封装一个状态管理,减少一个包的安装就可以减小打包以后的项目体积。 主要分两步:

  • 封装一个顶层组件提供数据
  • 子组件获取数据和更新数据

封装一个父组件用来包裹其他子组件

stores/index.js 文件中首先需要调用 createContext

export const MyContext = React.createContext({list: [], data: null, time: Date.now()});

createContext 中的参数是默认值,只有当组件所处的树中没有匹配到 Provider 时,其参数才会生效。

每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。

创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中匹配离自身最近的Provider,并从中读取到当前的 context 值。

context 可以设置一个displayName 的属性, 可以方便在React DevTool 对该context调试。

MyContext.displayName = 'MyManagementDisplayName';

Provider 接收一个 value 属性,传递给消费组件。 Context 能让你将这些数据向组件树下所有的组件进行“广播”,所有的组件都能访问到这些数据,也能访问到后续的数据更新。

这里我们封装一个父组件用来包裹其他子组件。

import { createContext, useReducer } from 'react';

// 纯函数reducer
function reducer(state, action) {
    // action包括 具体的类型type,
    // 除了 `type` 之外,action 对象的结构其实完全取决于你自己。
    // 这里使用了payload代表dipatch传过来的数据
    switch(action.type) {
        case 'list':
            return ({...state, list: action.payload});
        case 'data':
            return ({...state, data: action.payload});
        case 'time':
            return ({...state, time: action.payload});
        default:
            return state;
    }
}
const list = [{num: 0, key: 0}, {num: 1, key: 1}, {num: 2, key: 2}];
export const MyContext = createContext({list: [], data: null, time: Date.now()});

function ContextProvider({children}) {
    const [state, dispatch] = useReducer(
        reducer,
        {list: list, data: null, time: Date.now()}
    );

    const value = {
        state,
        dispatch
    }
    return <MyContext.Provider value={value}>
        {children}
    </MyContext.Provider>
}

export default ContextProvider;

这里用到了useReducer, 用过redux的同学一定非常熟悉,这是因为redux的作者 dan abramov 加入了react开发团队, 是react的主要开发者。 第一个参数是一个处理数据的纯函数,第二个参数是 initialValue。 useReducer还有另一种用法可以接受函数作为第三个参数,可以惰性地创建初始 state,这不是本文的重点,感兴趣的同学可以自行查询文档学习

在入口文件index.js中 用 ContextProvider 包裹 App 组件

import ReactDOM from 'react-dom';
import App from './App';
import './styles/index.less';

import ContextProvider from './stores';
ReactDOM.render(
    <ContextProvider><App /></ContextProvider>,
    document.getElementById('root')
);

子组件如何获取数据呢

有3种方式

  • Class Component 内获取(本方法仅能订阅 1 个 context)
  • context.Consumer
  • useContext

class Component 方式

import {MyContext} from '@/store';

class MyClass extends React.Component {
  static contextType = MyContext;
  // 引入的MyContext 赋值给静态属性 contextType后,
  // React可以让你使用 `this.context` 来获取最近 Context 上的值。
  componentDidMount() {
    let value = this.context;
    
  }
  componentDidUpdate() {
    let value = this.context;
    
  }
  componentWillUnmount() {
    let value = this.context;
    
  }
  render() {
    let value = this.context;
    
  }
}

context.Consumer

<context.Consumer>
  {value => /* 基于 context 值进行渲染* /}
</context.Consumer>

useContext

这是使用 hook 方式, 也是目前最流行的用法,后面的例子主要使用这个方式来演示。 因为我们要在很多需要全局状态的子组件使用,所以我们可以封装一下。

在 hooks/useStores.js

import {MyContext} from '@/stores';
import React from 'react';

// 封装代码以复用
const useStores = () => React.useContext(MyContext);

export default useStores;

下面我们通过两个组件,分别演示 获取数据并展示更新全局数据

views/footer/index.js
在此组件里获取全局数据并展示

import { useEffect } from 'react';
import useStores from '../../hooks/useStores';

function Footer() {
  const { state } = useStores();
  const { time, list } = state;
  useEffect(() => {
    console.log('Footer page rendered!!!')
  })
  return (
    <div style={{ height: 200 }}>
      <div>time now is {time}</div>
      <div>
        list is
        {list.map((item) => (
          <span 
              style={{
                  background: 'pink',
                  padding: '0 10px',
                  border: '1px solid',
                  marginRight: '10px'
              }}
              key={item.key}
          >
              {item.num}
          </span>
        ))}
      </div>
    </div>
  );
}

export default Footer;

views/header/index.js

我们在此组件里更新全局数据

import useStores from '../../hooks/useStores';
import { Link } from 'react-router-dom';
import { useEffect } from 'react';

function Header() {
  // 解构获取 dispatch 方法
  const { dispatch } = useStores();
  const handleList = () => {
    const payload = [...new Array(3)].map(() => {
      const key = Math.random();
      const num = Math.floor(key * 100);
      return ({
        key, num
      });
    })
    // 更新数据,订阅状态的组件都会获取更新通知并取到最新数据
    dispatch({ type: "list", payload });
  };
  return (
    <div style={{ height: 100 }}>
      <button onClick={() => dispatch({ type: 'time', payload: Date.now() })}>
        time
      </button>
      <button onClick={handleList}>list</button>
    </div>
  );
}

export default Header;

点击 header 中的按钮,footer 里的 time list 都会响应改变,获取到最新的值并渲染展示。

总结

我们通过封装顶层组件提供全局数据,子组件获取和更新数据, 完全基于 React 实现了一个简单的状态管理。

当然 Context 是可以嵌套多层的,同学们可以自行尝试

参考

  • React Context
  • React useReducer

 到此这篇关于基于React Context实现一个简单的状态管理的示例代码的文章就介绍到这了,更多相关React Context状态管理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 基于ReactContext实现一个简单的状态管理的示例代码

本文链接: https://www.lsjlt.com/news/154280.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于ReactContext实现一个简单的状态管理的示例代码
    目录前言封装一个父组件用来包裹其他子组件子组件如何获取数据呢class Component 方式context.ConsumeruseContext总结参考前言 在大多数情况下,我们...
    99+
    2024-04-02
  • 基于springboot实现一个简单的aop实例
    简介 AOP(Aspect-Oriented Programming:面向切面编程) aop能将一些繁琐、重复、无关业务的逻辑封装起来,在一个地方进行统一处理,常用于日志记录、事务...
    99+
    2024-04-02
  • 基于Python实现一个简单的学生管理系统
    目录序言代码实战效果展示序言 小学妹说要毕业了,学了一学期Python等于没学,现在要做毕设做不出来,让我帮帮她,晚上去她家吃夜宵。 当时我心想,这不是分分钟的事情,还要去她家,男孩...
    99+
    2022-12-31
    Python实现学生管理系统 Python学生管理系统 Python管理系统
  • C++实现一个简单的线程池的示例代码
    目录一、设计二、参数选择三、类设计一、设计 线程池应该包括 保存线程的容器,保存任务的容器。为了能保证避免线程对任务的竞态获取,需要对任务队列进行加锁。为了使得工作线程感知任务的到来...
    99+
    2024-04-02
  • Java实现一个简单的长轮询的示例代码
    目录分析一下长轮询的实现方式长轮询与短轮询配置中心长轮询设计配置中心长轮询实现客户端实现服务端实现分析一下长轮询的实现方式 现在各大中间件都使用了长轮询的数据交互方式,目前比较流行的...
    99+
    2024-04-02
  • java实现一个简单的网络爬虫代码示例
    目前市面上流行的爬虫以python居多,简单了解之后,觉得简单的一些页面的爬虫,主要就是去解析目标页面(html)。那么就在想,java有没有用户方便解析html页面呢?找到了一个jsoup包,一个非常方便解析html的工具呢。使用方式也非...
    99+
    2023-05-30
    网络爬虫 java jsoup
  • Java实现简单的银行管理系统的示例代码
    目录项目描述分析示例代码项目描述 银行管理系统目前支持,存款,取款,查询功能 分析 bank类:用来存放系统所支持的功能—存款,取款,查询 deal_service:用来...
    99+
    2024-04-02
  • Pinia怎么实现简单的用户状态管理
    这篇“Pinia怎么实现简单的用户状态管理”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Pinia怎么实现简单的用户状态管理...
    99+
    2023-07-04
  • 基于ASP.NET实现单点登录(SSO)的示例代码
    目录背景逻辑分析代码实现Service总结背景 先上个图,看一下效果: SSO英文全称Single Sign On(单点登录)。SSO是在多个应用系统中,用户只需要登录一次就可以访...
    99+
    2024-04-02
  • 基于Echarts实现绘制立体柱状图的示例代码
    目录前言实现方法先写一个常规的柱状图echarts的配置选项效果图前言 大家好,我是梁木由。之前在做大屏可视化项目时,UI设计了一个立体形状的柱状图,根据之前做的一些图表的项目没有能...
    99+
    2023-02-23
    Echarts绘制立体柱状图 Echarts立体柱状图 Echarts柱状图
  • 基于Qt实现简易GIF播放器的示例代码
    目录一、项目介绍二、项目基本配置三、UI界面设计四、主程序实现4.1 mainwindow.h头文件4.2 mainwindow.cpp源文件五、效果演示一、项目介绍 利用Qt设计一...
    99+
    2024-04-02
  • 基于JS实现动态跟随特效的示例代码
    目录演示技术栈源码css部分js部分演示 技术栈 这次用到了关于css的一些功能,和jQuery。 CSS3中添加的新属性animation是用来为元素实现动画效果的,但是anim...
    99+
    2024-04-02
  • 基于JS实现一个简单的投票demo
    目录演示说明源码body设置js实现投票的动画css设定演示 说明 今天没有什么好的内容分享,跟大家讲一个标签吧增长姿势。 line-height CSS 属性用于设置多行元素的空...
    99+
    2024-04-02
  • 基于Java实现一个简单的单词本AndroidApp的实践
    目录布局设计代码AddDanciActivity.javaDBOpenHelper.java       &nb...
    99+
    2024-04-02
  • 基于Python实现一个简易的数据管理系统
    目录创建mysql数据表增删改查启动应用 为了方便的实现记录数据、修改数据没有精力去做一个完整的系统去管理数据。因此,在python的控制台直接实现一个简易的数据管理系统,包括数据的...
    99+
    2024-04-02
  • Django实现简单登录的示例代码
    目录创建django项目使用模型的url.py加载静态文件页面跳转创建数据库模型提交表单提交ajax提交创建django项目 创建项目的命令行语句: django-admin st...
    99+
    2024-04-02
  • springboot简单实现单点登录的示例代码
    什么是单点登录就不用再说了,今天通过自定义sessionId来实现它,想了解的可以参考https://www.xuxueli.com/xxl-sso/ 讲一下大概的实现思路吧:这里有...
    99+
    2024-04-02
  • react实现组件状态缓存的示例代码
    目录前言一、安装第三方库二、配置操作总结前言 在移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个...
    99+
    2023-02-24
    react 组件状态缓存 react 组件缓存
  • 基于C语言实现静态通讯录的示例代码
    目录一、项目要求二、Contact.h三、Contact.c1、静态函数2、初始化通讯录3、打印4、增加联系人信息5、通过名字查找6、删除联系人信息7、修改信息8、排序通讯录9、清空...
    99+
    2024-04-02
  • 基于C++实现一个简单的音乐系统
    目录一、前言二、实现步骤三、代码实现四、讲解程序一、前言 2022临近尾声,2023即将来临。 过去的一年,我们同努力,我们共欢笑.。 每一次成功都蕴藏着我们辛勤的劳动。 新的一年即...
    99+
    2022-12-29
    C++音乐系统 C++声音系统 C++ Beep
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作