IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React-redux全局状态管理 -> 正文阅读

[JavaScript知识库]React-redux全局状态管理

这篇博客是看一个网上视频的笔记,后面也会根据自己在项目开发过程中遇到的问题进行不断的更新。

目录

Redux概述

什么是Redux

Redux的设计初衷

Redux三大核心

1、单一数据源

2、state是只读的

3、使用存函数来执行修改

Redux组成部分

state状态

action

reducer

?Store

Redux案例

react-redux

Redux概述

什么是Redux

Redux是一个用于Javascript状态容器,可以进行全局状态管理。

Redux可以构建一致化的应用,运行与不同的环境(客户端,服务器,原生应用),并且易于测试。

Redux除了和React一起使用外,还支持其他界面库,而且它体积很小(2KB)。

Redux的设计初衷

随着Javascript单页面开发日益复杂,Javascript需要管理更多的state(状态),这些state可能包括服务器响应、缓存数据、本地生成未持久化到服务器的数据,也包括UI状态等。

管理不断变化的state非常麻烦,如果一个model的变化会引起另外model的变化,那么当view发生变化时,就可能引起对应model以及另一个model的变化,依次可能引起其他view的变化,所以逻辑处理就会比较混乱。而Redux就为了解决这个问题的。Redux可以进行全局状态管理。

Redux三大核心

1、单一数据源

整个应用的state都被保存在一个object tree中,Object Tree只存在于唯一的一个store中。

2、state是只读的

说state是只读的,并不意味着state不能修改。

如果修改state需要触发一个action。action是一个用于描述已发生事件的普通对象。

这样确保了视图和网络请求都不能直接去修改state。它们只能表达想要修改的意图。所有的修改都会被集中化处理,并且按照一个接一个的顺序执行。

3、使用存函数来执行修改

为了描述action如何改变state,需要编写reducers。

reducers是一些纯函数,它接收先前的state和action,并且返回新的state。

可以复用、控制顺序、传入附加参数。

Redux组成部分

state状态

state就是我们传递的数据。state可以分为三类:

(1)DomainDate:从服务器请求到的数据

(2)UI state:控制UI展示的状态,比如弹框的显示隐藏等

(3)App state:App级别的状态,比如路由信息可以被多个组件使用到的状态

action

action是把数据从应用传到store载体,它是store数据的唯一来源,可以通过store.dispatch()将action传递给store

reducer

reducer本质就是一个函数,可以响应发送过来的action,经过处理,将state发送给store。

注意:在reducer函数中,需要return返回值,这样store才能接收到数据。

函数会接收两个参数,第一个参数是初始化state,第二个是action

?Store

store就是把action与reducer联系到一起的对象。

store维持应用的state状态,提供getState()方法获取state,提供dispatch()方法发送action,通过subscribe()注册监听,通过subscribe()返回值注销监听

redux的工作流程

?

?组件component通过action载体向store中发送数据,store通过reducers将新的state存到store中,其他组件就可以从store中拿到新的state状态。

类似于去图书馆借书的流程

?

Redux案例

构建项目之后,安装redux,安装命令:

npm i redux

在scr文件夹下创建action文件夹,并在action文件夹下创建index.js文件。在index.js中通过创建一个函数,返回一个aciton对象,其中action对象中必须要有type属性。

/**
 * action 构建函数
 */
export const sendAction = () => {
    // 需要返回一个action对象,该action对象需要包括type等属性
    return {
        type: 'send-action',
        value: '这是一个action'
    }

}

接着在src文件夹下创建reducer文件夹,在reducer文件夹中创建index.js文件。在index.js文件中处理action,通过return将数据传给store.

/**
 * 该文件是创建reducer函数,专门用于处理发送过来的action
 */

const initState = {
    value: '默认值'
}
// 函数需要传递两个参数:state,action
const rootReducer = (state = initState, action) => {
    console.log('reducer:', state, action)
    // 根据aciton中的type字段判断是否为发送过来的action,如果是则返回一个新的state
    switch (action.type) {
        case 'send-action':
            return Object.assign({}, state, action)
        default:
            return state
    }
}
export default rootReducer;

接着利用createStore来构建store,createStore方法中传入reducer。

import { createStore } from 'redux'
import { rootReducer } from '../reducer';
const store = createStore(rootReducer)

export default store;

在Home组件中通过store.subscribe()注册监听,当利用store.dispatch()发送action时就会触发监听,然后就可以通过store.getState()方法获取数据

import React from "react";
// 引入store
import store from '../../store'
// 引入action构建函数
import {sendAction} from '../../action'

export default class Home extends React.Component {
    constructor(props) {
        super(props)
    }

    sendAction() {
        // 通过sendAction创建一个action
        const action = sendAction()
        // 发送一个action
        store.dispatch(action)
    }

    componentDidMount() {
        // 注册监听
        this.unsubscribe = store.subscribe(() => {
            // 通过getState()方法获取state
            console.log('subscribe: ', store.getState())
            // 获取到监听之后,可以通过this.setState()方法触发页面重新渲染
            this.setState({})
        })
    }
    componentWillUnmount() {
        // 取消监听
        this.unsubscribe()
    }
    render() {
        return (
            <div>
                <button onClick={this.sendAction.bind(this)}>发送action</button>
                <p>store获取的值:{store.getState().value}</p>
            </div>
        )
    }
}

结果:

未点击发送action之前:

点击发送aciton之后:

上面的示例,我们会发现每创建一个store,我们就需要导入该store,并且要注册/取消监听,比较麻烦,react-redux为我们解决了这个问题。

react-redux

第一步:安装依赖:

npm install redux

npm install react-redux

第二步:按redux的示例创建action、reducer、store等方法,然后创建两个组件,并引入到app.js中。

第三步:引入Provider

在app.js中引入react-redux库中的Provider组件,用Provider组件包裹项目结构,并给Provider设置store属性,传入我们创建的store。这样Provider就可以统一维护store了。

import CompA from "./page/CompA";
import CompB from "./page/CompB";
import store from '../src/store'

// 导入Povider组件,利用这个组件包裹项目结构,从而统一维护store
import { Provider } from "react-redux";


function App() {
  return (
    // 为Provider传入store
    <Provider store={store}>
      <div className="App">
        <CompA />
        <CompB />
      </div></Provider>

  );
}

export default App;

第三步:使用react-redux库中的connect

Provider只是维护store,真正使用store还需要connect。connect可以把组件和store进行关联。

connect的使用方法的简单介绍:

使用方法:connect(...)(组件)?

ps:connect(...)返回的是一个方法,所以才能继续跟(组件)

connect(...)的参数说明:

具体详情可以查看react-redux官方文档对connect的讲解

?其中mapStateToProps和mapDispatchToProps比较重要。

mapStateToProps: (state, ownProps?) => Object,哪个组件需要接收store的数据,就实现该方法,如果不想订阅store更新可以传入null或者undefined代替mapStateToProps

mapDispatchToProps?: Object | (dispatch, ownProps?) => Object,哪个组件需要发送store数据,就实现该方法。

发送方CompA

import React from "react";
// 导入connect方法
import { connect } from "react-redux";
class CompA extends React.Component {

    addCount() {
        console.log('CompA: ', this.props)//由日志可以发现sendAction会被传过来
        // 所以我们就可以利用sendAction发送数据
        this.props.sendAction()
    }
    render() {
        return (
            <div>
                CompA组件:<button onClick={this.addCount.bind(this)}>增加</button>
            </div>
        )
    }
}
//创建mapDispatchToProps方法-使用箭头函数实现,最后action会被作为一个props传递给组件
const mapDispatchToProps = (dispatch) => {
    // 需要返回一个对象
    return {
        // 对象使用key-value的形式。另外根据对redux使用可以知道sendAction也是一个方法实现
        sendAction: () => {
            // 利用dispatch发送一个action
            dispatch({
                // action必须要有type属性
                type: 'add-action'
            })
        }

    }
}

/*
CompA是数据发送方,所以要实现connect的第二个参数mapDispatchToProps
 */

export default connect(null, mapDispatchToProps)(CompA)

接收方CompB

import React from "react";
// 导入connect方法
import { connect } from "react-redux";

class CompB extends React.Component {
    render() {
        return (
            <div>
                CompB组件接收到的数据:{this.props.count}
            </div>
        )
    }
}
const mapStateToProps = (state) => {
    // 在这里必须要return state
    return state

}
// 接收方
export default connect(mapStateToProps, null)(CompB)

reducer:

const initState = {
    count: 0
}
export const rootReducer = (state = initState, action) => {
    console.log('reducer:', state, action)
    switch (action.type) {
        case 'add-action':
            // 在reducer中返回了新的state,才能触发相关的接收组件获取新的数据
            return {
                count: state.count + 1
            }
        default:
            return state
    }
}

store

import { createStore } from 'redux'
import { rootReducer } from '../reducer';
const store = createStore(rootReducer)

export default store;

数据传递流程

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:22:00  更:2022-02-26 11:24:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:24:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码