React多组件状态共享之Redux

什么是Redux

2013年 Facebook 提出了 Flux 架构的思想,引发了很多的实现。2015年,Redux 出

现,将 Flux 与函数式编程结合一起,很短时间内就成为了最热门的前端架构。

Redux的官方解释是:Redux is a predictable state container for JavaScript apps. 意思

就是Redux是js应用的一种可预测的状态容器。

此处需要说明的是flux和redux与 react都没有关系,redux和flux可以用在任何框架中,因

为flux和redux是完整的架构,使用react开发项目的时候,只是将react的组件作为redux

中的视图层去使用。

react设计理念是单向数据流,而我们在用react构建前端应用的时候,通常需要获取其他

组件的状态,如果组件繁多,获取修改其状态就比较麻烦,这时候就用到了redux。

在这里插入图片描述

Redux组成部分

store:数据的管理者和数据的存储者;

actionCreators:动作的创建者,发送动作给reducers

react Components:react组件,用来充当视图层

reducers:数据的修改者,返回一个新的newstate给store,它是一个纯函数

为什么使用Redux

React 只是 DOM 的一个抽象层,并不是 Web 应用的完整解决方案。有两个方面,它没

涉及。

(1)代码结构

(2)组件之间的通信

没有使用Redux的情况,如果两个组件(非父子关系)之间需要通信的话,可能需要多个中

间组件为他们进行消息传递,这样既浪费了资源,代码也会比较复杂。

Redux中提出了单一数据源Store 用来存储状态数据,所有的组建都可以通过Action修改

Store,也可以从Store中获取最新状态。使用了redux就可以完美解决组建之间的通信问题。

Redux的使用的三大原则:

(1)Single Source of Truth(唯一的数据源)

(2)State is read-only(状态是只读的)

(3)Changes are made with pure function(数据的改变必须通过纯函数完成)

Redux使用场合

如果你不知道是否需要 Redux,那就是不需要它,只有遇到 React 实在解决不了的问

题,你才需要 Redux。

简单说,如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加

复杂性,比如:

(1)用户的使用方式非常简单

(2)用户之间没有协作

(3)不需要与服务器大量交互,也没有使用 WebSocket

(4)视图层(View)只从单一来源获取数据

但是如果你开发的项目,满足下面的条件,那么这时候就需要Redux登场了:

(1)用户的使用方式复杂

(2)不同身份的用户有不同的使用方式(比如普通用户和管理员)

(3)多个用户之间可以协作

(4)与服务器大量交互,或者使用了WebSocket

(5)View要从多个来源获取数据

从组件层面考虑,满足下列要求,就需要使用Redux:

(1)某个组件的状态,需要共享

(2)某个状态需要在任何地方都可以拿到

(3)一个组件需要改变全局状态

(4)一个组件需要改变另一个组件的状态

Redux的使用

下面以一个计数案例来说明redux的具体使用流程

(1)安装redux

yarn add redux

(2)在src文件夹下新建store文件夹(此处默认使用create-react-app已安装好项目),

然后在store文件夹中,新建index.js、reducers.js、actionCreators.js、state.js文件

(3)分别打造上面三个文件

state.js–存放数据

const state={
    num:0
}

export default state

reducers.js–是一个纯函数

//1.该函数有两个参数
//第一个参数是唯一数据源,需要赋值初始数据,第二个参数是actionCreators中发来的动作action
//2.拷贝一层数据源,进行这个数据源的修改
//3.返回值:返回新的状态
//4.使用switch,判断用户的动作类型,进行对应的数据修改

import state from './state'
const reducers=(prevState = state , action)=>{

    //拷贝初始数据,生成新的状态值
    const newState={
        ...prevState
    }
    return newState//返回拷贝出来的新的值
}
export default reducers

index.js

import { createStore } from 'redux'
import reducer from './reducers' 
const store = createStore( reducer )
export default store 

(4)在你想要的组件中直接引用store

import React, { Component } from 'react';
import  store from '../store'//引入store中的数据
console.log(store.getState())
class Count extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            count:store.getState().num//将store中的数据赋给count
         }
    }
    render() { 
        return ( 
            <div>
                <button>+</button>
                <p>num:{this.state.count}</p>//展示数据
            </div>
         );
    }
}
 
export default Count;

(5)打造actionCreators.js文件

// 创建动作,并发送动作,引入动作的类型
import * as type from './type'

import store from './index'//引入store,为了使用store中的dispatch方法来发送动作

console.log(store)
const actionCreators={
    increasement( val ){//此处的val来自于组件调用该方法时,传递过来的参数
        let action={//定义动作
            type:type.INCREASEMENT,
            payload:val//该负载可有可无,根据组件在调用increasement方法时是否传递参数来决定
        }
        store.dispatch(action)//发送动作
    }
}

export default actionCreators

(6)在reducer.js中根据动作类型,对数据进行操作

import state from './state'

import * as type from './type'
const reducers=(prevState = state , action)=>{

    //拷贝初始数据,生成新的状态值
    const newState={
        ...prevState
    }
    switch (action.type) {
        case type.INCREASEMENT:
            console.log(action)//此处有输出action,那么说明在actionCreator中定义的动作,已成功
            newState.num++
            break;
    
        default:
            break;
    }
    return newState
}

export default reducers

(7)最后在组件中【此处是react中的组件】使用actionCreators.js中的方法即可

import React, { Component } from 'react';

import  store from '../store'

import  actionCreators from '../store/actionCreators'

console.log(store.getState())

class Count extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            count:store.getState().num
         }
    }

    add=()=>{
                actionCreators.increasement('hello')//此处的hello就是传递给actionCreators.js中的val
                                                    //可根据需要传递改参数,
    }

    componentDidMount(){
        //视图的更新,需要事件的发布和订阅,在redux中不需要写事件的发布,
        //只需要写订阅,store中的subscribe的方法,就是订阅,将数据的修改写在
        //subscribe中的回调函数内部
        store.subscribe(()=>{
            this.setState({
                    count:store.getState().num
            })
        })
    }

    render() { 
        return ( 
            <div>
                <button onClick={this.add}>+</button>
                <p>num:{this.state.count}</p>
            </div>
         );
    }
}
 
        export default Count;
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值