javascript Redux的状态管理详解

所谓的状态管理,就是对应用程序中的数据进行管理。

理念:凡是数据流管理混乱的项目,几乎都上不了线。好的项目,必须有非常良好的数据流管理。

如何使用Redux?记住“3个3”。

第1个三:3个api,createStore、combineReducers、applyMiddleware

第2个三:3个特点,store单一数据源、store只读的、只能通过reducer纯函数来修改store。

第3个三:3个概念,store、action、reducer。

基本概念:

  • state 包含所有数据,用来给store提供数据
  • store 就是状态管理数据,可以被React共享的数据,数据容器,保存数据的地方
  • action 是一种信号,可以用来修改state的信号,固定格式:{type,payload},可以这样理解,type是邮件标题,payload是邮件内容

示例:在src目录下新建store文件夹,新建index.js

// store/index.js
import { createStore } from 'redux'
// 定义在redux中的数据,可被Reac组件共享
const initState = {
    count: 1,
    msg: 'hello world'
}
// state参数,就是状态管理数据,可以被React共享的数据
// action是一种信号,可以用来修改state的信号
// action的格式是固定的{type,payload}
function reducer(state = initState, action) {
    return state
}
const store = createStore(reducer)
export default store

在src下新建目录views,good,GoodList.js

// views/good/GoodList.js
export default props => {
    console.log('GoodList props', props);
    return (
        <div>
            <h1>商品列表页</h1>
        </div>
    )
}

App.js

// 引入Provider来提供数据
import { Provider } from 'react-redux'
import store from '@/store';
import GoodList from '@/views/good/GoodList';
// store就是state
function App() {
  return (
    <Provider store={store}>
      <GoodList />
    </Provider>
  );
}
export default App;

打印GoodList props为空,直接使用props是拿不到数据的

问题:在这个函数式组件中,如何与redux关联

答案

1.connect高阶组件,它是把redux相关的数据和方法,放到props上。

2.hooks,它是直接访问,与props无关

connect  语法:connect(mapStateToProps,mapDispatchToProps)

理解:mapStateToProps用于把store数据放在props上,mapDispatchToProps用于把修改store的方法放到props上

改造views/good/GoodList.js:

import { connect } from 'react-redux'
// 语法:connect(mapStateToProps,mapDispatchToProps)(UI组件)
// 理解:mapStateToProps用于把store数据放在props上,mapDispatchToProps用于把修改store的方法放到props上
function mapStateToProps(state) {
    console.log('上下文中的store', state);
    // 把获得的数据return出去,props才会接收到
    return {
        count: state.count,
        msg: state.msg
    }
}
function mapDispatchToProps(dispatch) {
    // dispatch用于派发一个信号(action),信号可以修改store
    console.log('dispatch', dispatch);
    return {
        // 需求:添加方法使count自增或自减
        add: function () {
            // 在这里通过 dispatch 向store派发一个'自增'的信号
            const action = { type: 'add', payload: 1 }
            dispatch(action)
        },
        sub: function () {
            const action = { type: 'sub', payload: 1 }
            dispatch(action)
        }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(
    props => {
        console.log('GoodList props', props);
        return (
            <div>
                <h1>商品列表页</h1>
                <h1>{props.count}</h1>
                <button onClick={props.add}>自增</button>
                <button onClick={props.sub}>自减</button>
            </div>
        )
    }
)

store会接收到信号,改造store/index.js:

// store/index.js
import { createStore } from 'redux'
// 定义在redux中的数据,可被Reac组件共享
const initState = {
    count: 1,
    msg: 'hello world'
}
// state参数,就是状态管理数据,可以被React共享的数据
// action是一种信号,可以用来修改state的信号
// action的格式是固定的{type,payload}
function reducer(state = initState, action) {
    console.log('信号', action);
    // 由于store是只读的,直接修改state是不会更新视图的
    // 所以对store进行深复制
    let newState = JSON.parse(JSON.stringify(state))
    if (action.type === 'add') {
        newState.count += action.payload
    }
    if (action.type === 'sub') {
        newState.count -= action.payload
    }
    // console.log('newState',newState)
    return newState
}
const store = createStore(reducer)
export default store

最终效果:

当然,代码中还有很多可以改进的地方,例如,通常我们不使用connect,而是使用Hooks函数来直接访问store里面数据,而无需通过props

  • useSelector() 用于访问上下文中的redux数据
  • useDispatch() 得到dispatch方法,可以向redux派送

将views/good/GoodList.js改造成hooks函数写法,极大减少代码量

import { useSelector, useDispatch } from "react-redux";
// 注意:Hooks只能在函数式组件中使用
// - useSelector() 用于访问上下文中的redux数据
// - useDispatch() 得到dispatch方法,可以向redux派送action
export default () => {
    // 访问根state中study子模块中的count
    const count = useSelector(state => state.count)
    const dispatch = useDispatch()
    const add = (payload) => dispatch({ type: 'add', payload })
    const sub = (payload) => dispatch({ type: 'sub', payload })
    return (
        <div>
            <h1>商品列表页</h1>
            <h1>{count}</h1>
            <button onClick={() => add(1)}>自增</button>
            <button onClick={() => sub(1)}>自减</button>
        </div>
    )
}

以及我们还可以通过produce来实现深复制: produce:第一个参数就是传入旧的state,经过内部深复制,在第二个函数中可以拿到深复制的结果;在回调函数中对深复制的结果进行修改(加工),最终修改的结果就是produce的返回值,

将store/index.js改造如下:

import { produce } from 'immer'
// 定义在redux中的数据,可被Reac组件共享
const initState = {
    count: 1,
    msg: 'hello world'
}
function reducer(state = initState, action) {
    // immer深复制
    // produce:第一个参数就是传入旧的state,经过内部深复制,在第二个函数中可以拿到深复制的结果;在回调函数中对深复制的结果进行修改(加工),最终修改的结果就是produce的返回值
    return produce(state, (newState) => {
        switch (action.type) {
            case 'add':
                newState.count += action.payload
                break
            case 'sub':
                newState.count -= action.payload
                break
            default:
        }
    })
}
export default reducer

还可以使用 logger 中间件更加直观的查看数据流

import { createStore, combineReducers, applyMiddleware } from 'redux'

import logger from 'redux-logger'

const store = createStore(reducer, applyMiddleware(logger))

export default store

使用效果如图:

redux工作原理示意图

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 详解JavaScript状态容器Redux

    目录 一.Why Redux 二.Redux Data flow 三.Three Principles(三大原则) 四.Redux源码解析 4.1.index.js 4.2.createStore.js 4.3.combineReducers.js 4.4.bindActionCreators.js 4.5.compose.js 4.6.applyMiddleware.js 五.从零开始实现一个简单的Redux 六.Redux Devtools 七.总结 一.Why Redux 在说为什么用 R

  • 如何用RxJS实现Redux Form

    写在前面的话 看这篇文章之前,你需要掌握的知识: React RxJS (至少需要知道 Subject 是什么) 背景 form 可以说是 web 开发中的最大的难题之一.跟普通的组件相比,form 具有以下几个特点: 1.更多的用户交互. 这意味着可能需要大量的自定义组件,比如 DataPicker,Upload,AutoComplete 等等. 3.频繁的状态改变. 每当用户输入一个值,都可能会对应用状态造成改变,从而需要更新表单元素或者显示错误信息. 3.表单校验,也就是对用户输入数据的有

  • redux.js详解及基本使用

    什么是Redux ​      Redux我们可以把它理解成一个状态管理器,可以把状态(数据)存在Redux中,以便增.删.改.例如: 从服务器上取一个收藏列表,就可以把取回来的列表数据用Redux管理,多个页面共享使用,不用把数据传来传去. A页面改变了一个状态,B页面要收到通知,做相应的操作. ​       Redux是一个给JS应用使用的可预测的状态容器,也就是说结果是可预测的,每一次改动会有确定的结果,正如函数式编程思想里的相同的参数会返回相同的结果. ​       Redux的状态

  • react.js框架Redux基础案例详解

    react.js框架Redux https://github.com/reactjs/redux 安装: npm install redux react-redux #基于react,我们在前面已经安装过了 Redux参考文档: http://redux.js.org/ Redux核心概念:Store 我们可以简单的理解为就是用来存储 各个组件的State或你自己定义的独立的state,对state进行统一读取.更新.监听等操作. http://redux.js.org/docs/basics/

  • JSP状态管理的简单介绍

    JSP状态管理的简单介绍 一 http协议的无状态性 无状态性是指:当浏览器发送请求给服务器时,服务器响应客户端请求. 但是当同一个浏览器再次发送请求给服务器的时候,服务器并不知道它就是刚才那个浏览器. 简单地说,就是服务器不会去记得你,所以就是无状态协议. 二 保存用户状态的两大机制 Session Cookie 三 Cookie概述 Cookie:中文名称为"小甜饼",是Web服务器保存在客户端的一系列文本信息. 典型应用一:判断注册用户是否已经登录网站. 典型应用二:"

  • javascript-hashchange事件和历史状态管理实例分析

    本文实例讲述了javascript-hashchange事件和历史状态管理.分享给大家供大家参考,具体如下: hashchange事件 hashchange事件,可以监听URL参数(#后面的字符串)什么时候发生变化. 代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport"

  • 一篇看懂vuejs的状态管理神器 vuex状态管理模式

    关于vuex类的新闻最近很多,看到眼热就去查了下资料,然后扯出来一堆flux.redux.state.state之类的概念,以及大型工程必要性之类的.看官方手册也是昏昏然. 然而,我还是弄懂了!我准备从demo出发,以同样的一个最简单的demo,演示两种情况下的代码编写情况: 单纯依赖于vue.js 依赖vue.js,也使用了vuex技术 目的是通过对比引出vuex的概念.优势和劣势.也许这是目前最接地气的vuex的介绍吧:).所以无论如何在了解vuex之前,你必须懂得vue.js(好像废话:)

  • 24行JavaScript代码实现Redux的方法实例

    前言 Redux是迄今为止创建的最重要的JavaScript库之一,灵感来源于以前的艺术比如Flux和Elm,Redux通过引入一个包含三个简单要点的可伸缩体系结构,使得JavaScript函数式编程成为可能.如果你是初次接触Redux,可以考虑先阅读官方文档. 1. Redux大多是规约 考虑如下这个使用了Redux架构的简单的计数器应用.如果你想跳过的话可以直接查看Github Repo. 1.1 State存储在一棵树中 该应用程序的状态看起来如下: const initialState

  • javascript Redux的状态管理详解

    所谓的状态管理,就是对应用程序中的数据进行管理. 理念:凡是数据流管理混乱的项目,几乎都上不了线.好的项目,必须有非常良好的数据流管理. 如何使用Redux?记住“3个3”. 第1个三:3个api,createStore.combineReducers.applyMiddleware 第2个三:3个特点,store单一数据源.store只读的.只能通过reducer纯函数来修改store. 第3个三:3个概念,store.action.reducer. 基本概念: state 包含所有数据,用来

  • 基于React Hooks的小型状态管理详解

    目录 实现基于 React Hooks 的状态共享 使用感受 本文主要介绍一种基于 React Hooks 的状态共享方案,介绍其实现,并总结一下使用感受,目的是在状态管理方面提供多一种选择方式. 实现基于 React Hooks 的状态共享 React 组件间的状态共享,是一个老生常谈的问题,也有很多解决方案,例如 Redux.MobX 等.这些方案很专业,也经历了时间的考验,但私以为他们不太适合一些不算复杂的项目,反而会引入一些额外的复杂度. 实际上很多时候,我不想定义 mutation 和

  • vue前端开发辅助函数状态管理详解示例

    目录 mapState mapGetters mapMutations mapActions 示例 小结 mapState 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余.为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性.不使用mapState时,获取对象状态,通常放在使用组件的computes属性中,使用方式为: //.... computed: { count: function(){ return this.$store.state

  • flutter自定义InheritedProvider实现状态管理详解

    目录 InheritedWidget简单数据驱动模型 1. 数据存储 2. 变更通知 3. 使用方法 InheritedWidget简单数据驱动模型 基于InheritedWidget,实现简单的数据驱动模型,模型结构如下: 1. 数据存储 使用 InheritedWidget,新建 InheritedProvider import 'package:flutter/material.dart'; class InheritedProvider<T> extends InheritedWidg

  • Mobx实现React 应用的状态管理详解

    目录 MobX 从一个 demo 开始 创建类并将其转化成可观察对象 使用可观察对象 MobX 与 React 集成 在组件中使用可观察对象 1. 访问全局的类实例 2. 通过 props 3. 通过 React Context 4. 在组件中实例化 observable class 并存储它的实例 5. 在组件中调用 observable 方法创建可观察对象 6. 在函数组件中使用 useLocalObservable 让组件具备观察能力 总结 MobX MobX 是一个状态管理库,它会自动收

  • vue之使用vuex进行状态管理详解

    目录 vuex进行状态管理 vuex状态管理基本使用 vuex进行状态管理 首先学习vuex必须先知道vue原理 Vue是一个典型的MVVM框架,模型(Model)只是普通的JavaScript对象,修改它则视图(View)会自动更新.这种设计让状态管理变得非常简单而直观 Vue实现这种数据双向绑定的效果,需要三大模块: Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更

  • vue3如何使用provide实现状态管理详解

    目录 前言 如何通过 provide/inject 实现 Vuex的功能 在应用中注册此插件 插件的入口文件 创建 store ,把对应的数据挂载到根组件上 实现 mapState.mapMutations 和 mapActions方法 组件中使用 总结 前言 在 Vue 生态中, Vuex 这个官方的状态管理库在 Vue 应用开发中,为我们带来了非常便捷的功能.但是 Vuex 20K+ 的大小,也带来了一些成本,对于项目规模较小的应用来说, 引入 Vuex 只是为了存储用户信息之类的一小撮数据

  • React状态管理Redux的使用介绍详解

    目录 1. 简介 2. 核心概念 3. redux工作流 4. 模拟redux工作流程 5. 使用redux 6. react-redux 1. 简介 Redux 是 JavaScript 应用的状态容器(对象),提供可预测的状态管理.可以让你开发出行为稳定可预测的应用,运行于不同的环境(客户端.服务器.原生应用),并且易于测试.Redux 除了和 React 一起用外,还支持其它界面库. 解决的问题:多层级组件间通信问题. 2. 核心概念 单一数据源 整个redux中的数据都是集中管理,存储于

  • JavaScript设计模式之命令模式和状态模式详解

    目录 命令模式 命令模式介绍 代码实现 状态模式 状态模式介绍 代码实现 小结 命令模式 命令模式介绍 命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及执行可撤销的操作. 也就是说改模式旨在将函数的调用.请求和操作封装成一个单一的对象,然后对这个对象进行一系列的处理.此外,可以通过调用实现具体函数的对象来解耦命令对象与接收对象. 代码实现 <!DOCTYPE html> <html lang=&qu

  • React immer与Redux Toolkit使用教程详解

    目录 1. immer 1.1 setState结合immer使用 1.2 useState结合immer使用 1.3 immer和redux集合 2. Redux Toolkit 1. immer 概述: 它和immutable相似的,实现了操作对象的数据共享,可以优化性能.它实现的原理使用es6的Proxy完成的.小巧,没有像immutable哪样有新数据类型,而是使用js类型. 安装: yarn add immer@9 1.1 setState结合immer使用 简单使用: import

随机推荐