首页 > 编程语言 >React - 28 redux部分源码解析

React - 28 redux部分源码解析

时间:2023-06-11 12:33:03浏览次数:49  
标签:function listener const reducer 28 React state 源码 action

myRedux.js

import _ from './assets/utils';

/* 实现redux的部分源码 */
export const createStore = function createStore(reducer) {
    if (typeof reducer !== 'function') throw new Error("Expected the root reducer to be a function");

    let state, //存放公共状态
        listeners = []; //事件池

    /* 获取公共状态 */
    const getState = function getState() {
        // 返回公共状态信息即可
        return state;
    };

    /* 向事件池中加入让组件更新的方法 */
    const subscribe = function subscribe(listener) {
        // 规则校验
        if (typeof listener !== "function") throw new TypeError("Expected the listener to be a function");
        // 把传入的方法(让组件更新的办法)加入到事件池中「需要做去重处理」
        if (!listeners.includes(listener)) {
            listeners.push(listener);
        }
        // 返回一个从事件池中移除方法的函数
        return function unsubscribe() {
            let index = listeners.indexOf(listener);
            listeners.splice(index, 1);
        };
    };

    /* 派发任务通知REDUCER执行 */
    const dispatch = function dispatch(action) {
        // 规则校验
        if (!_.isPlainObject(action)) throw new TypeError("Actions must be plain objects");
        if (typeof action.type === "undefined") throw new TypeError("Actions may not have an undefined 'type' property");

        // 把reducer执行,传递:公共状态、行为对象;接收执行的返回值,替换公共状态;
        state = reducer(state, action);

        // 当状态更改,我们还需要把事件池中的方法执行
        listeners.forEach(listener => {
            listener();
        });

        return action;
    };

    /* redux内部会默认进行一次dispatch派发,目的:给公共容器中的状态赋值初始值 */
    const randomString = () => Math.random().toString(36).substring(7).split('').join('.');
    dispatch({
        // type: Symbol()
        type: "@@redux/INIT" + randomString()
    });

    // 返回创建的STORE对象
    return {
        getState,
        subscribe,
        dispatch
    };
};

src/store/index.js

import { createStore } from '../myredux';

/* 管理员:修改STORE容器中的公共状态 */
let initial = {
    supNum: 10,
    oppNum: 5
};
const reducer = function reducer(state = initial, action) {
    // state:存储STORE容器中的公共状态「最开始没有的时候,赋值初始状态值initial」
    // action:每一次基于dispatch派发的时候,传递进来的行为对象「要求必须具备type属性,存储派发的行为标识」
    // 为了接下来的操作中,我们操作state,不会直接修改容器中的状态「要等到最后return的时候」,我们需要先克隆
    state = { ...state };
    // 接下来我们需要基于派发的行为标识,修改STORE容器中的公共状态信息
    switch (action.type) {
        case 'VOTE_SUP':
            state.supNum++;
            break;
        case 'VOTE_OPP':
            state.oppNum++;
            break;
        default:
    }
    // return的内容,会整体替换STORE容器中的状态信息
    return state;
};

/* 创建STORE公共容器 */
const store = createStore(reducer);
export default store;

标签:function,listener,const,reducer,28,React,state,源码,action
From: https://blog.51cto.com/u_12207234/6457419

相关文章

  • 5.28学习总结thread多线程理解
    多线程早在大二刚来的时候就听王建民老师提到过,但是当时觉得多线程肯定很难,而且现在也用不到,就没有接触。现在看来多线程的学习还是比较简单的。下面演示代码均为PythonfromthreadingimportThreadth=thread(target=,args=())#target指向新线程执行的目标函数,args中......
  • 5.28
    5.29号今日总结 今天下午进行了期末测试,如下是题目和代码:河北宏志大学学生成绩管理系统1、项目需求:学生管理是各大院校的管理工作中尤为重视的一项工作,它一直以来是学校管理的一项重要的衡量指标。学生管理系统的应用解决了学校日常学生管理工作中的信息量大、数据难以......
  • VideoEye源码编译错误记录
    最近在研究雷神的开源项目VideoEye,但是下载编译时用VS2013和VS2015都出现一些报错。分析是因为雷神调试的环境是VS2010,现在使用新版本VS编译时存在不兼容的问题。网上查找各种信息,最终问题得以解决,于是乎记录一下。【背景】项目地址http://git.oschina.net/leixiaohua1020/Vid......
  • 5.28学习总结
    CSS分页实例本章节我们将为大家介绍如何通过使用CSS来创建分页的实例。简单分页如果你的网站有很多个页面,你就需要使用分页来为每个页面做导航。以下实例演示了如何使用HTML和CSS来创建分页:CSS实例ul.pagination {    display: inline-block;    paddin......
  • 获取微信小程序源码
    获取微信小程序源码的三种方法:一、使用adb连接手机获取小程序源码1、手机root环境下开启调试模式,手机通过USB数据线连接电脑查看设备adb.exedevices连接设备adb.execonnect10.10.10.1//ip为手机IP2、手机未root环境下adbusbadbdevicesadbtcpip8888//设置端口号888......
  • Go语言之gin框架源码学习
    Go语言之gin框架源码学习gin框架路由注册与路由匹配、中间件packagemainimport( "fmt" "github.com/gin-gonic/gin" "net/http")funcfunc1(c*gin.Context){ fmt.Println("func1")}funcfunc2(c*gin.Context){ fmt.Println("func2......
  • 算法刷题记录:P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布
    题目链接https://www.luogu.com.cn/problem/P1328题目分析是一道和环有关的问题,直接模拟即可AC代码//Problem:P1328[NOIP2014提高组]生活大爆炸版石头剪刀布//Contest:Luogu//URL:https://www.luogu.com.cn/problem/P1328//MemoryLimit:125MB//TimeLimit......
  • 数学老师从没这么教过,乘法竖式中进位可以是多位(附Python实现与测试源码)...
    大概十五年前,曾经写过一个C语言版本的类似代码。核心思想是:在乘法竖式计算过程中,每次的进位实际上是可以超过一位的,虽然老师从来没有这么教过。这样的操作在Python中是没有必要的,因为Python中的数字没有大小限制。但在C语言或其他静态类型语言中,由于整型变量能够表示的范围有限,所以......
  • 构建高效互联网医院系统:源码开发技巧
    目前来看,互联网医院系统源码的构建成为了医院信息化建设的一个重要方向。在构建高效互联网医院系统的过程中,源码开发技巧显得尤为重要。本篇文章,小编将为大家着重讲述一下,希望对您有一定的帮助。一、系统整体架构设计理论上来讲,整体架构的开发就是互联网医院系统的核心之一,在这个过......
  • 【React工作记录九十六】docker部署前后端项目在云服务器
    前言大家好我是歌谣最近开始前端和后端的学习需要部署项目在服务器上面命令部分目前只会部署的部分前端前彻底端的目录是在/ngng/html下面dockerrestartngng重新启动容器前端文件放置后端后端的文件在project下面步骤1dockerstopgeo2dockerrm-fgeo3dockerrmi-fgg......