谁都能听懂的Redux+Redux-Saga超级傻瓜教程

对不起本文确实有标题党的嫌疑:) 想要理解本文仍是要先会用reactes6,若是连reactes6都不知道是什么的话我也没辙:( html

 

若是你选择用react来开发应用,而且你没对各个组件的状态进行应有的管理,那么当应用变得庞大的时候你会发现组件之间的通讯变得错综复杂,各个组件之间的数据传递每每会乱成一团,从而致使加班、延期、炒鱿鱼等很差的事情:( 这个时候就须要引入“状态管理”这个概念来挽救一团乱麻的代码。状态管理,就是将各个组件之间相互独立的状态和数据给统一的管控起来,让本来错综复杂的数据流向变成单向,这样状态就变得容易管理和理解,从而让程序变得易于维护。react

 

今天咱们讲的就是react目前最流行的状态管理工具redux和它的一些周边组件。废话很少说,咱们先准备好react开发环境,打开ide开始敲代码。webpack

 

环境这块我就不讲了,最基础的webpack+react便可。git

首先先安装reduxyarn add redux -S),清空src目录,新建一个入口js文件(index.js),输入如下内容:es6

 

import { createStore } from 'redux'

const reducer = function (state, action) {
  console.log(action.type)
  return state
}

const store = createStore(reducer)

store.dispatch({type: 'hello'})

 

 

 

而后启动dev server,打开浏览器和控制台,就能够看到输出了“hello”。如今来稍微解释下这段代码:github

createStore,从字面上理解,就是建立仓储,这个仓储用来存放数据和修改数据的方法。web

 

dispatch,直译过来是指派、调度,能够理解成命令store执行修改数据的操做。传入一个对象来描述要执行的动做。咱们称这个对象为actionajax

 

reducer,直译过来是还原剂,这里就把它理解成存放数据和修改数据的方法的地方。若是把store比喻成仓库,那么reducer就是用来装载货物的集装箱。reducer接受的第一个参数是数据,第二个参数用来描述动做,里面是dispatch过来的对象和数据,咱们能够利用type属性结合switch case语句来进行具体的状态修改。还有要记得返回state,若是没有返回state就会报错。redux

 

咱们把reducer扔到createStore这个函数里,就返回了一个store。而后再调一下store里面的dispatch方法,就执行了一次reducer。这样一个最简单的redux管理状态的流程就跑完了。浏览器

在这个例子里咱们只使用了一个reducer,而一个reducer只有一个state,可是咱们的应用确定不止一个组件,这个时候就须要多个reducer

为了将多个reducer组合起来,咱们又要引入一个redux里的函数,叫combineReducers

import {combineReducers, createStore} from 'redux'

const list = function (state = [], action) {  //state=[]表示的是state的初始状态
  console.log(action.type)
  console.log('list')
  return state
}

const counter = function (state = 0, action) {
  console.log(action.type)
  console.log('counter')
  return state
}

const reducers = combineReducers({
  list, counter
})

const store = createStore(reducers)

store.dispatch({type: 'hello'})

 

 

这样就将多个reducer组合起来了。调用dispatch的时候全部reducer都会被执行。

 

 

到了这里咱们就已经能够进行一些简单的本地状态管理了。可是几乎全部的应用都有涉及到ajax异步请求,这些代码要放到哪里呢?若是放到reducer里的话因为reducer要求当即返回state,否则报错。解决方案是有的,不过有些繁琐,能够参考阮一峰老师的教程:

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html

若是没看懂的话也不要紧,若是你可以在项目中运用redux-saga的话,就能够很轻松的解决异步问题了:)

咱们先认真的把redux-saga官方提供的案例给看一看

https://redux-saga-in-chinese.js.org/docs/introduction/BeginnerTutorial.html

redux-saga的使用很简单,和以前redux的作法差很少。先定义saga(也称为effect。相似reducer,不过能够调用异步方法,不能修改状态),而后在顶层(index.js)注册以前写好的saga便可。

sagaeffect)中,咱们能够经过takeEvery来监听dispatch,经过call来调用异步方法,经过put来触发reducer,经过select来获取状态。要注意的是saga都是Generator函数(带*号),也只有Generator函数里才能调用yield。这样异步问题就差很少解决了。

 

说了这么多,总得应用到react里面去吧。react里的各个组件想要获取到store里的状态和命令store进行数据修改,若是不安装其余包的话就只能在根级组件把store一级一级的传递下去,中间有一级没传递store那么以后的组件就所有没法使用redux进行状态管理了,这样显然是有待改进的。因此咱们还要再装一个包:react-redux

React-redux核心的方法只有两个:ProviderconnectProvider用来包裹根级组件,并接收storeconnect用来将组件的propsstore链接起来,这样即便不一层层的传递store每一个组件也能够接收到store

export default connect((state) => {
  return {list: state.userList.list} // 将store与组件链接起来。connect第一个参数是一个函数,要求返回用来描述props和store的对象。
})(List) 

 

 

这样咱们基本上就能把redux给实际的应用起来了,可是还有一个问题值得咱们思考:store调用dispatch后全部的reducer都会被执行,而每一个reducer里面只能用switch case之类的流程控制语句来指定执行哪一个reducer,若是项目一大,各个方法的命名岂不是很容易混乱?别着急,这个时候须要本文要谈到的最后一个包:dvajsdvajs将一组数据和相应的修改数据的方法包装成一个module,组件调用dispatch的时候能够经过指定type属性来直接调用相应moduleeffect或者reducerdvajs的具体使用除了参考官网的案例之外,还能够参照这篇博文:http://www.javashuo.com/article/p-aehwfnrz-eu.html。只要你可以从redux->redux-saga->react-redux这个流程学下来,就会发现dvajs几乎没有多少新知识点,很快就可以上手。

若是以为教程里有地方讲的不是很理解的能够将下面这个案例下载下来看一看,相信不少问题都会获得答案。

一个在线获取用户列表,点击项目可删除的例子

https://github.com/axel10/react-redux-redux-saga-example

相关文章
相关标签/搜索