广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >简易的redux createStore手写实现示例
  • 763
分享到

简易的redux createStore手写实现示例

手写redux createStoreredux createStore 2022-11-13 18:11:00 763人浏览 泡泡鱼
摘要

目录1.首先创建一个store2.其次创建一个my-redux书写getState()方法书写dispatch方法书写subscribe方法特别注意:3.创建一个Test组件进行检测

1.首先创建一个store

沙箱链接

根目录创建一个store文件夹,下面创建一个index.js

import { createStore } from '../my-redux'
// 书写reducer函数
function reducer(state = 0, action) {
    switch (action.type) {
        case "add":
            return state + 1;
        case "inc":
            return state - 1;
        default:
            return state;
    }
}
// 使用createStore(reducer)创建store对象并且导出
const state = createStore(reducer);
export default state;

结合上面的代码分析

  • 创建store是redux库的createStore函数接收一个reducer函数进行创建。
import { createStore } from '../my-redux'
  • 先手写一个简单的reducer函数
// 书写reducer函数
状态值默认为0
function reducer(state = 0, action) {
    switch (action.type) {
        case "add":
            return state + 1;
        case "inc":
            return state - 1;
        default:
            return state;
    }
}
  • 将创建的store导出
// 使用createStore(reducer)创建store对象并且导出
const state = createStore(reducer);
export default state;

2.其次创建一个my-redux

  • 将所有的函数都导入index.js

import createStore from './createStore'
export {
    createStore
}
  • 创建一个createStore.js
export default function createStore(reducer) {
    let currentState; // 当前state值
    let currentListeners = []; // store订阅要执行的函数储存数组
    // 获得当前state值
    function getState() {
        return currentState;
    }
    // 更新state
    function dispatch(action) {
        // 传入action 调用reducer更新state值
        currentState = reducer(currentState, action)
        // 遍历调用订阅的函数
        currentListeners.forEach((listener) => listener());
    }
    // 将订阅事件储存到currentListeners数组,并返回unsubscribe 函数来取消订阅
    function subscribe(listener) {
        currentListeners.push(listener);
        // unsubscribe 
        return () => {
            const index = currentListeners.indexOf(listener);
            currentListeners.splice(index, 1);
        };
    }
    dispatch({ type: "" }); // 自动dispatch一次,保证刚开始的currentState值等于state初始值
    // 返回store对象
    return {
        getState,
        dispatch,
        subscribe,
    }
}

可以根据上面给出的代码步步分析:

①明确createStore接收一个reducer函数作为参数。

②createStore函数返回的是一个store对象,store对象包含getState,dispatch,subscribe等方法。

  • 逐步书写store上的方法

书写getState()方法

返回值:当前状态值

// 获得当前state值
    function getState() {
        return currentState;
    }

书写dispatch方法

接受参数:action。

dispatch方法,做的事情就是:①调用reducer函数更新state。②调用store订阅的事件函数。

currentState是当前状态值,currentListeners是储存订阅事件函数的数组。

    // 更新state
    function dispatch(action) {
        // 传入action 调用reducer更新state值
        currentState = reducer(currentState, action)
        // 遍历调用订阅的函数
        currentListeners.forEach((listener) => listener());
    }

书写subscribe方法

接受参数:一个函数 返回值:一个函数,用于取消订阅unsubscribe

    // 将订阅事件储存到currentListeners数组,并返回unsubscribe 函数来取消订阅
    function subscribe(listener) {
        currentListeners.push(listener);
        // unsubscribe 
        return () => {
            const index = currentListeners.indexOf(listener);
            currentListeners.splice(index, 1); // 删除函数
        };
    }

返回store对象

    // 返回store对象
    return {
        getState,
        dispatch,
        subscribe,
    }

特别注意:

初始进入createStore函数的时候,需要通过dipatch方法传入一个独一无二的action(reducer函数默认返回state)来获取初始的store赋值给currentStore。

可以结合下面reducer的default项和createStore方法调用的dispatch来理解

 dispatch({ type: "" }); // 自动dispatch一次,保证刚开始的currentState值等于state初始值
// 书写reducer函数
function reducer(state = 0, action) {
    switch (action.type) {
        case "add":
            return state + 1;
        case "inc":
            return state - 1;
        default:
            return state;
    }
}

这样我们的createStore函数就已经完成了。那接下来就是检查我们写的这玩意是否起作用没有了。

3.创建一个Test组件进行检测。

老规矩先抛全部代码

import React, { Component } from 'react'
import store from './store' // 引入store对象
export default class Test extends Component {
    // 组件挂载之后订阅forceUpdate函数,进行强制更新
    componentDidMount() {
        this.unsubscribe = store.subscribe(() => {
            this.forceUpdate()
        })
    }
    // 组件卸载后取消订阅
    componentWillUnmount() {
        this.unsubscribe()
    }
    // handleclick事件函数
    add = () => {
        store.dispatch({ type: 'add' });
        console.log(store.getState());
    }
    inc = () => {
        store.dispatch({ type: 'inc' });
        console.log(store.getState());
    }
    render() {
        return (
            <div>
                {}
                <div>{store.getState()}</div>
                <button onClick={this.add}>+</button>
                <button onClick={this.inc}>-</button>
            </div>
        )
    }
}

1. 将Test组件记得引入App根组件

import Test from './Test';
function App() {
  return (
    <div className="App">
      <Test />
    </div>
  );
}
export default App;

2. 将store引入Test组件

import React, { Component } from 'react'
import store from './store' // 引入store对象

3. 创建一个类组件,并且使用store.getState()获得状态值

<div>
    {}
    <div>{store.getState()}</div>
    <button onClick={this.add}>+</button>
    <button onClick={this.inc}>-</button>
</div>

4. 书写对应的点击按钮

    // handleclick事件函数
    add = () => {
        store.dispatch({ type: 'add' });
        console.log(store.getState());
    }
    inc = () => {
        store.dispatch({ type: 'inc' });
        console.log(store.getState());
    }
    <div>
        {}
        <div>{store.getState()}</div>
        <button onClick={this.add}>+</button>
        <button onClick={this.inc}>-</button>
    </div>

这样是不是就可以实现了呢?哈哈哈,傻瓜,你是不是猛点鼠标,数字还是0呢?

当然,这里我们只是更新了store,但是并没有更新组件,状态的改变可以导致组件更新,但是store又不是Test组件的状态。

这里我们使用一个生命周期函数componentDidMount和store的订阅函数进行更新组件的目的,使用componentWillUnmount和store的取消订阅函数(订阅函数的返回值)。

    // 组件挂载之后订阅forceUpdate函数,进行强制更新
    componentDidMount() {
        this.unsubscribe = store.subscribe(() => {
            this.forceUpdate()
        })
    }
    // 组件卸载后取消订阅
    componentWillUnmount() {
        this.unsubscribe()
    }

好了。这里我们就真实实现了一个简单的createStore函数来创建store。

以上就是简易的redux createStore手写实现示例的详细内容,更多关于手写redux createStore的资料请关注编程网其它相关文章!

--结束END--

本文标题: 简易的redux createStore手写实现示例

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

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

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

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

下载Word文档
猜你喜欢
  • 简易的redux createStore手写实现示例
    目录1.首先创建一个store2.其次创建一个my-redux书写getState()方法书写dispatch方法书写subscribe方法特别注意:3.创建一个Test组件进行检测...
    99+
    2022-11-13
    手写redux createStore redux createStore
  • gomockserver的简易实现示例
    目录前言代码步骤1步骤2步骤3步骤4最终效果最后前言 学习golang也一段时间了,看了一些书,上周又看了一本入门级的《Go语言趣学指南》,是时候检验成果了。 目的:通过读取本地mo...
    99+
    2022-11-11
  • 利用Java手写一个简易的lombok的示例代码
    目录1.概述2.lombok使用方法3.lombok原理解析4.手写简易lombok1.概述 在面向对象编程中,必不可少的需要在代码中定义对象模型,而在基于Java的业务平台开发实践...
    99+
    2022-11-13
    Java手写lombok Java lombok
  • canvas简易绘图的实现示例
    小编给大家分享一下canvas简易绘图的实现示例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!图片如下:代码如下:<!DOCTYPE html&g...
    99+
    2023-06-09
  • python区块链简易版交易实现示例
    目录说明引言比特币交易交易输出发送币余额查看总结说明 本文根据https://github.com/liuchengxu/blockchain-tutorial的内容,用python...
    99+
    2022-11-11
  • go 实现简易端口扫描的示例
    我在代码里定义了两个通道,分别用于生产端口和限制连接数,如果不限制连接数,容易被对方检测到或导致对方服务器不能正常运行。 // 生产端口 var port = make(chan...
    99+
    2022-11-12
  • C#实现简易画图板的示例代码
    编程环境 VS2019、C# 画板功能演示 实现简单画图 打开功能 可打开jpg格式的文件 保存功能 可将绘画的内容保存为jpg文件 颜色选择功能 用户可自由选择所需的颜色...
    99+
    2022-11-12
  • Qt实现简易计时器的示例代码
    目录一、项目介绍二、项目基本配置三、UI界面设计四、主程序实现4.1 mainwindow.h头文件4.2 mainwindow.cpp源文件五、效果演示一、项目介绍 计时器实现四个...
    99+
    2022-11-13
  • 编写简易Android天气应用的代码示例
    本文所要介绍的简易天气App主要用RxAndroid、MVP、Retrofit实现,首先来看看效果: 主页内容: 右侧栏天气列表: 左侧栏城市列表 首先看看Acti...
    99+
    2022-06-06
    示例 Android
  • python自制简易mysql连接池的实现示例
    目录连接池是什么? 为什么需要连接池? 连接池的原理是什么? 使用python语言自制简易mysql连接池 开始使用 自定义配置文件名 & 配置标签 ...
    99+
    2022-11-12
  • Node.js实现的简易网页抓取功能示例
    现今,网页抓取已经是一种人所共知的技术了,然而依然存在着诸多复杂性, 简单的网页爬虫依然难以胜任Ajax轮训、XMLHttpRequest,WebSockets,Flash Sockets等各种复杂技术所开...
    99+
    2022-06-04
    示例 简易 功能
  • Python实现简易凯撒密码的示例代码
    目录概念及原理实现过程破解原理及实现概念及原理 根据百度百科上的解释,凯撒密码是一种古老的加密算法。 密码的使用最早可以追溯到古罗马时期,《高卢战记》有描述恺撒曾经使用密码来传递信息...
    99+
    2022-11-11
  • 基于统计的交易策略简易实现VNPY的示例分析
    这篇文章将为大家详细讲解有关基于统计的交易策略简易实现VNPY的示例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。交易思维是基于历史数据中,一组数据比如100天中,K线中最高点或者最低点...
    99+
    2023-06-02
  • JavaScript实现手写promise的示例代码
    目录背景需求then的链式调用Promise.all背景 promise 作为前端开发中常用的函数,解决了 js 处理异步时回调地狱的问题,大家应该也不陌生了,今天来学习一下 pro...
    99+
    2023-05-15
    JavaScript手写promise JavaScript promise
  • React的createElement和render手写实现示例
    目录TL;DR科普概念准备工作实现 createElement实现 render测试TL;DR 本文的目标是,手写实现createElement和render React.creat...
    99+
    2022-11-13
  • Mysql实现简易版搜索引擎的示例代码
    目录前言简介ngram 全文解析器创建全文索引检索方式1、自然语言检索(NATURAL LANGUAGE MODE)2、布尔检索(BOOLEAN MODE)与 Like 对比总结前言...
    99+
    2022-11-12
  • Qt实现简易毛玻璃效果的示例代码
    目录现有功能运行结果源码frosted_glass_label.hfrosted_glass_label.cppmain.cpp现有功能 1.用模糊功能实现简易的毛玻璃效果。 2.鼠...
    99+
    2022-11-13
  • golang 手写贪吃蛇示例实现
    目录背景需求构思逻辑构思代码结构小结 背景 题主现在是php程序员, 学了一周的golang, 深刻的感受到了其特性的优雅及功能的强大, 为了增强熟练度, 决定来写个贪吃蛇来践行下....
    99+
    2022-11-13
  • Matlab实现简易纪念碑谷游戏的示例代码
    按上下左右键(↑↓←→)移动物块 按AD键转动视角 游戏效果:如图所示原本无法通过的路径经过视角调整即可通过 完整代码 function...
    99+
    2022-11-13
  • 基于Qt实现简易GIF播放器的示例代码
    目录一、项目介绍二、项目基本配置三、UI界面设计四、主程序实现4.1 mainwindow.h头文件4.2 mainwindow.cpp源文件五、效果演示一、项目介绍 利用Qt设计一...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作