react梳理之redux

react状态管理,其实可以用很多东西,flux和react一同和facebook成长起来,但是flux数据模式是可以和react区分开来理解的,flux前端架构模式有很多应用的工具,我们既然是react梳理,我们就梳理一下redux和redux-react,有一些不了解的人会觉得,这俩不是一样的东西吗,不一样哦,看起来一样,实际上不一样的,redux-react看名称就知道是适用于react的,但是redux是适用于所有地方的

一. 什么是flux
  1. Flux的核心思想就是数据和逻辑永远单向流动
    众所周知,React提倡的是一种单向数据流,指的是父子组件之间的单向数据流。而Flux中的单向数据流则是在整体架构上的延伸。在Flux应用中,数据从action到dispatcher,再到store,最终到view的路线是单向不可逆的,各个角色之间不会像MVC模式中那样存在交错的连线
  2. 一个Flux应用由三大部分组成dispatcher,storeview
    dispatcher负责分发事件
    store负责保存数据,同时响应事件并更新数据
    view负责订阅store中的数据,并使用这些数据渲染相应的页面
  3. flux很重要的一点,就是只允许dispatch去修改数据,其他的任何方式都不被允许修改store数据,那么如此一来排除dispatche之外就只剩下数据store对所有使用者的数据分发了,也就完全保证了数据的单向流动
二. redux

redux是原生js通过发布订阅者模式来实现的一种状态管理,订阅发布者模式可以先看一下前边的设计模式之观察者模式,里边有讲到,简单说一下就是有一个中转站,订阅者参加订阅(传递方法被储存起来),发布者发布消息(遍历调用所有相关的订阅的方法),达到一个事情发生通知所有相关人员的目的,那我们的store数据也是这样的,我们需要所有使用我们store数据的地方在store发生改变的时候都能够知道且接收到相关信息

  1. redux重点内置方法
    subscribe(订阅)
    createStore(初始化数据/接收处理reducer)
    getState(获取store数据)
    combineReducers(拆分reducer)
    applyMiddleware(使用中间件)

  2. redux使用概念
    reducer(dispatch触发处理函数)
    actions(dispatch触发对象)
    actionsType(actions中type的命名抽离)

  3. redux使用
    对于redux的理解还是要从简到难来理解,有的人可能一看就懂,但是没有任何基础的人可能就是不太明白这个订阅发布者模式和redux的具体使用,很容易混淆概念方法,reducer和actions并不是redux导出的东西,只是一个我们通俗命名的一种概念,真正导出和使用的,最基础的是subscribe/createStore/getState,有这三个其实就已经可以使用简单的redux了
    createStore:最基础的肯定是要创建一个store对象了

//store/index.js
import { createStore } from 'redux'
import reducer from './reducer'
const state =  { text1: 222 }
export const store = createStore(reducer, state)

1.我们先说createStore,这个是从redux中导出的,能力就是创建一个store对象,可以接收两个参数,一个是reducer,一个是state,我们应该可以看出,state是什么,就是初始化的数据,初始化数据也可以不传,但是reducer必须要传的,我们再看reducer

//reducer.js
export default (state, action) => {
    const type = action.type
    switch (type) {
        case 'TEXT_ONE':
            return {
                ...state, ...{ text1: action.text1 }
            }

        default:
            return state
    }

}

2.reducer是什么,就是一个将来dispatch触发更改的时候要调用的函数,我们可以看作是一个回调的纯函数,什么叫纯函数,就是不受外界因素干扰,固定传值只会得到固定答案,我们看上边代码可以看到,reducer是一个概念因为我们并没有使用什么办法来生成,reducer只是一个固定了参数的函数,也就是说,我们可以随意传一个函数,然后会获得固定的参数
两个参数,一个是,因为是形参所以我们可以随意起名字,但是一般我们语义化规范都叫做stateaction,因为state是接收原本的仓库中的值(初始化的值或者本次修改之前一次修改的值),action是我们dispatch调用的时候传递的对象
reducer做的事就是接收旧的state和dispatch传递的参数,随意进行操作(一般都是把dispatch传递的值替换给旧有的值),然后返回一个需要储存的对象

//****.js
import React, { Component } from 'react'
import { store } from '../store'

export default class pageOne extends Component {
  constructor() {
    super()
    this.state = {
      text1: store.getState().text1
    }
  }
  componentDidMount() {
    store.subscribe(() => {
      this.setState({
        text1: store.getState().text1
      })
    })
  }
  render() {
    return (
      <div onClick={this.changeStore}>pageOne--{this.state.text1}</div>
    )
  }
  changeStore() {
    store.dispatch({
      type: 'TEXT_ONE',
      text1: 111
    })
  }
}

4.这就是实际应用中修改store中数据的方式,必须使用dispatch来触发,就像是react中必须使用setState来触发修改state一样,不允许dispatch之外的方法去修改值,也只有dispatch才会触发订阅者传递的方法的调用
5.subscribe:订阅者,具体作用就是订阅store数据,传递了一个回调函数,当store数据被dispatch更改的时候,这个方法就会被调用,我们可以在任何地方写这个订阅,每个页面都能有自己的订阅,然后再自己的页面进行一些操作,达到数据更改更新视图的目的

我们说了这些其实已经可以最简单的使用redux了,所以我们来梳理一下

  1. 我们需要通过createStore来创建一个仓库,里边需要传递一个回调函数(我们称之为reducer),回调函数会拿到两个参数,旧有值和dispatch新传的值,回调函数制定修改的规则,且返回一个修改后的仓库
  2. 我们在使用的页面要加subscribe去订阅,当store被任何地方的dispatch修改值的时候,传递的方法会被调用,我们可以进行自己的逻辑
  3. 在任何地方都可以dispatch,与subscribe没有任何关联,dispatch中传递一个对象(我们称之为action),对象内有type和修改的数据

好接下来我们继续说扩展说一下reducer和actions

  • reducer的拆分使用combineReducers,当我们的reducer处理情况变多了之后,我们就需要拆分reducer,其实是一定意义上是在拆分store仓库,拆分成多个
import {combineReducers} from 'redux'
function changeName(state,action){ //形参默认值
    switch(action.type){
        case 'CHAN_NAME':
            return { ...state, ...{ name: action.name } }
        default:
            return state
    }
}
function changeAge(state,action){
    switch(action.type){
        case 'CHAN_AGE':
            return { ...state, ...{ age: action.age } }
        default:
            return state
    }
}

export const finalReducer = combineReducers({
    changeName,changeAge
})

拆分之后,我们使用了一个combineReducers来给两函数做了一个集合的作用,毕竟我们给createStore传递的参数也是很严格的,不能随便啥都同意给传,所以如果要拆分的话一定得用combineReducers,然后调用state的时候要换成store.getState().changeName.name,这个不熟悉也没事,因为没啥难度,可以暂时先用,等有拆分的需要的时候自然也就懂了

  • action的异步与优化
  1. 优化主要是代码方面的优化,更好看一些,我们从上边的代码来看能看出来,实际上我们的dispatch调用的时候,写这个type和传递数值很丑,因为写的又是字符串又是对象的,不够干脆利落,所以我们大概都会把这个对象(也就是所谓的action)放在一个专门的地方,我们就叫做action.js,当然了不想这样做也可以
const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux'
};
//或者下边这样
const ADD_TODO = '添加 TODO';

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
//使用的时候这样
store.dispatch(action)//缺点就是传递的值变固定了,所以我们一般不会这样
//或者这样
store.dispatch(addTodo('Learn Redux'));
  • 异步action:applyMiddleware加载异步中间件
import {createStore,applyMiddleware} from 'redux'
import reducers from './reducers'
import thunk from 'redux-thunk'
const store = createStore(reducers,applyMiddleware(thunk));

我们一般会用两个处理异步的中间件,一个是redux-thunk,一个是redux-promise

//redux-thunk允许action返回一个回调函数,回调函数可以接受到dispatch方法,可以起到延迟调用的作用
export const changeAge= (age) =>{
    return dispatch =>{
        setTimeout(()=>{
            dispatch(addTodo(age))
        },2000);
    }
}
//redux-promise可以接受返回一个promise对象,等到执行结束接受到真正的action会自动dispatch
export const changeAge= (age) =>{
    return new Promise(function(resolve, reject){
        setTimeout(function(){
             resolve(addTodo(age))
        }, 2000);
    });
}
  • actionsType这个我就不说了,多看两眼,这个其实就纯粹是为了代码美观和编辑报错了

总结: redux这几步其实非常简单,理解东西一定要从最原始最基本的去理解,别想着上来就给action/reducer一下子理解完全,我建议看这个之前还是先看看订阅发布模式,因为了解订阅发布模式,这个真的就是一眼看穿了,明天说一下react-redux,稍微封装的更深了一些的redux罢了,远离不变,只不过dispatch和subscribe变成了高阶组件罢了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值