Redux初探

Redux初探_第1张图片

在这张图中,我们可以很清晰的看到,view中产生action,通过store.dispatch(action)将action交由reducer处理,最终根据处理的结果更新view。
在这个过程中,action是简单对象,用于描述一个动作以及对应于该动作的数据。

我们来看下redux到底是如何工作的。



import React from 'react'
import { createStore, bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import ReactDom from 'react-dom'
import { Provider } from 'react-redux'

function createAction(){
return{
type: 'ADD_TODO',
data: 'some data'
}
}

class App extends React.Component{
constructor() {
super();
}
render() {
return(
width:'200px',
height:'200px',
margin:'100px',
border:'2px solid black'
}}>
this.props.actions.createAction.bind(this)
}> {"Click Me!"}


) ;
}
}

function mapStateToProps(state){
return{
data: state
}
}

function mapDispatchToProps(dispatch){
return{
actions: bindActionCreators({createAction}, dispatch)
}
}

var AppApp = connect( mapStateToProps, mapDispatchToProps)(App);

function reducer(state, action){
console.log(action);
return state;
}

var store = createStore(reducer);

ReactDom.render(



, document.getElementById('container'));

  • 这是一个精简版本的redux demo,每点击一次“Click Me!”,控制台会打印一次action。

    下面是截图:
    Redux初探_第2张图片
    效果图
  • 控制台打印输出:
    Redux初探_第3张图片
    控制台打印
  • 从上面代码中可以清晰的看出,
    当用户点击“Click Me!”的时候,会立即调用createAction产生一个action,之后redux获取这个action并调用store.dispatch将这个action丢给reducer进行处理,demo中的reducer仅仅打印了action。
    数据从view中流出,经reducer处理后又回到了view。
    至此,我们看到的一切都是跟上面的基本认知是一致的。

Redux Middleware


  • redux为我们做了很多的事情,我们都可以不用通过显示的调用dispatch函数就将我们的action传递给reducer。
    但是redux一直没有解决异步的问题。试想,如果我在页面输入一段内容,然后触发了一个搜索动作,此时需要向服务端请求数据并将返回的数据展示出来。
    涉及到异步请求,刚刚的demo中的方法已经不再适用了,需要引入middleware。

  • 我们看看redux-thunk的代码:
    一个三目符,如果action是一个函数,执行这个action函数,如果不是函数,执行next函数。


    export default function thunkMiddleware({ dispatch, getState }) {
    return next => action =>
    typeof action === 'function' ? action(dispatch, getState) : next(action);
    }

  • 结合middleware的应用:


    const finalCreateStore=applyMiddleware(thunkMiddleware)(createStore)
    const store = finalCreateStore(reducer)

  • 这就是我们最常使用middleware的代码。把源码中的next换成createStore,如果action是一个函数(这里的action是改造后的ActionCreator),便会执行这个action(dispatch, getState)函数。


    var asyncSayActionCreator = function (message) {
    return function (dispatch) {
    setTimeout(function () {
    dispatch({ type: 'SAY', message })
    }, 2000) }
    }

  • 这里的action是return的函数:


    function (dispatch) {
    setTimeout(function () {
    dispatch({ type: 'SAY', message })
    }, 2000)
    }

  • 如果action返回的不是函数,即返回的是action对象的话,执行createStore函数的dispatch方法。
    有了middleware之后,数据流动的方向变为:
    action ---> dispatcher ---> middleware 1 ---> middleware 2 ---> reducers

自己的middleware怎么写?


学了这些,我们可以自己写一个middleware练练手。首先在项目下建个middlewares的文件夹,新建一个callTraceMiddleware.js来追踪函数的调用过程。在funCallTrace.js添加如下代码:


export default function callTraceMiddleware ({dispatch,getState}){
return next=> action =>{
console.trace();
return next(action);
}
}

然后在调用中间件部分添加中间件:


const createStoreWithMiddleware = applyMiddleware( thunkMiddleware, loggerMiddleware, callTraceMiddleware)(createStore);

这样我们运行在浏览器窗口就可以看到打印的函数调用轨迹。是不是很简单……

你可能感兴趣的:(Redux初探)