Redux

Redux

Flux,Redux,React-redux概念

严格意义上来说,React 只是MVC架构中的View层,并不是 Web 应用的完整解决方案,因此,只用 React 没法实现大型应用。为了解决这个问题,2014年 Facebook 提出了 Flux 架构的概念,并在2015年推出Redux,将 Flux 与函数式编程结合一起,在很短时间内就成为了最热门的前端架构。

  • 什么是Redux:Redux 是一种新型的前端“架构模式”(Flux 架构的一种变种),它不关注你到底用什么库,你可以把它应用到 React 和 Vue,甚至跟 jQuery 结合都没有问题。

  • React和Redux:事实上是两个独立的产品,项目中可以使用 React 而不使用
    Redux ,也可以使用 Redux 而不使用 React

  • 什么是React-redux:就是把 Redux 这种架构模式和 React.js 结合起来的一个库,是 Redux 架构在 React.js 中的体现,利用这个库能够大大简化代码的书写

什么时候需要Redux

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

  • 某个组件的状态,需要共享
  • 某个状态需要在任何地方都可以拿到
  • 在一个组件中需要改变全局状态
  • 在一个组件中需要改变另一个组件的状态

Redux 的工作流程

Alt text

基本概念

核心对象:Store

store是Redux存储区(一个保存数据的地方),你可以把它看成一个仓库,规定一个应用只能有一个Store,store中的数据可以被直接访问,但只能通过提供的reducer进行更新。

  • 生成数据仓库方法:createStore()
    import { createStore } from 'redux';
    const store = createStore(reducer);//reducer为一个纯函数,用于设定state修改逻辑(如何修改state中的数据)
  • 常用方法
    • getState() 获取仓库最新状态(数据)
    • dispatch(action) 操作数据
    • subscribe(fn) 监听数据修改

数据存储:State

state为数据状态(快照,即数据在某个时间点的状态),State改变则View改变

    store.getState();//获取某一个数据状态(对store生成快照)

状态更新提交:Dispatch

修改数据操作

    store.dispatch(action);//是 View 发出 Action 的唯一方法

状态更新提交参数:Action

Action用于定义如何改变state,是用户改变 State 的唯一方式,

  • 格式:{type:'UPDATE_CART',payload}
    • type: 一个简单的字符串常量,例如ADD, UPDATE, DELETE等。
    • payload: 用于更新状态的数据。
  • 使用方式:
    store.dispatch({type:'UPDATE_CART',{num:100});

Action Creator

每次编写action对象比较麻烦,可以封装一个函数用于生成action

    export function updateCart(todo){
        return {
            type:'UPDATE_CART',
            payload:todo
        }
    }

状态更新逻辑:Reducer

Reducer 必须是一个纯函数,用于指定state修改逻辑,它接受当前 state 和 action 作为参数,并根据state和action的值返回新的state

纯函数:返回结果由参数来决定,不对参数做修改操作,不产生任何副作用

    //设置默认值
    let defaultState = {goodslist:[],step:0}
    let cartReducer = (state=defaultState,action)=>{
        switch(action.type){
            case 'UPDATE_CART';
                return {...state,goodslist:action.payload}

            default:
                return state;
        }
        
    }
处理多个Reducer:combineReducers
    import { createStore,combineReducers } from "redux";
    const productsReducer = function(state=[], action) {
      return state;
    }
    //合并Reducer
    const allReducers = {
      products: productsReducer,
      shoppingCart: cartReducer
    }

    const rootReducer = combineReducers(allReducers);
    let store = createStore(rootReducer);

React-Redux

Alt text

为了方便使用,Redux 的作者封装了一个 React 专用的库 React-Redux,它提供了一些接口,用于Redux的状态和React的组件展示结合起来,以用于实现状态与视图的一一对应

组件分类

根据功能不同,React-Redux 将所有组件分成两大类:

1)UI 组件
  • 职责简单,只负责 UI 的呈现,不带有任何业务逻辑
  • 没有状态(即不使用this.state这个变量)
  • 所有数据都由参数(props)提供
  • 不使用任何 Redux 的 API
2)容器组件
  • 负责管理数据和业务逻辑,并把数据通过prop传入UI组件(自身不负责 UI效果)
  • 带有内部状态
  • 使用 Redux 的 API

React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成

如果一个组件既有 UI 又有业务逻辑,那怎么办?解决方案是,将它拆分成下面的结构:

  • 外面是一个容器组件,里面包了一个UI 组件。
  • 前者负责与外部的通信,将数据传给后者,由后者渲染出视图

组件<Provider>

  • React-Redux 提供Provider组件,接受Redux的store作为props,并将其声明为context的属性之一
  • 可结合connect方法可以让容器组件方便获取state和dispatch
    ReactDOM.render(
        <Provider store={store}>
            <App/>
        </Provider>,
        document.getElementById('app')
    )

connect()

connect方法为React-Redux核心方法,它把react组件与redux中的Store真正连接在一起,connect方法接受两个参数(Function类型),用于定义了 UI 组件的业务逻辑,返回容器组件

  • 格式:connect([mapStateToProps],[mapDispatchToProps])

mapStateToProps

顾名思义,将state中的数据映射到UI组件的props,

  • 特点:每当state更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染

  • 负责组件的输入逻辑,即将state映射到 UI 组件的参数(props)

  • 必须返回一个对象

mapDispatchToProps

  • 负责组件的输出逻辑,即将用户对 UI 组件的操作映射成 Action
  • 必须返回一个对象
    function mapStateToProps(state,ownprops) {
        //state:redux中的state
        //ownprops: Cart组件自身的props
      return {
        //将state中购物车页面的goodslist数据映射到props,Cart组件中通过props.data访问
        data: state.shoppingCart.goodslist
      }
    }
    function mapDispatchToProps(dispatch,ownprops) {
        // dispatch: redux中的dispatch方法
        // ownprops:同上
      return {
        onChangeQty: (action) => dispatch(action),
        onRemoveGoods: (action) => dispatch(action),
      }
    }
    Cart = connect(mapStateToProps,mapDispatchToProps)(Cart);

调式Redux程序

  1. 在谷歌应用商店下载redux-devtools
  2. 安装redux-devtools-extension
    npm install -save-dev redux-devtools-extension
  1. 引入并使用
    //store/index.js
    import {composeWithDevTools } from 'redux-devtools-extension';
    const store = createStore(rootReducer,composeWithDevTools());
    export default store;
  1. 在Chrome浏览器中调试redux程序

Redux测试工具

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值