对于react-redux的理解梳理

框架

浏览数:614

2019-3-9

由于前段时间做react的一个框架,顺便用上了react-redux,在这里将自己的理解记录下来,给自己增加些印象,顺便希望能帮助一些使用react-redux的萌新们。

网上已有大堆资料介绍react-redux,它是redux和react结合的一个框架,我们可以说是用来专门管理自己数据业务(或逻辑状态)的一个框架。所以在这里我们首先过一遍redux是什么?

redux

redux就是用来统一管理项目中的状态(state)。state它可以是前后端的各种数据,也可以是UI上的一些信息。简单点,它就是个对象,包含了项目中可能用于改变的一些信息。

redux重要关注的几点:ActionsReducersStore,下面就分别来看看吧。

1、Actions:

function changeTable(index) {
        return { type: "channgTable", data:index }
}

以上例子就是一个action,我们不用纠结它定义个一个函数形式还是其它,最终它就是一个对象。包含type、data或者还有其他元素的对象。

action就是用来告诉我们的状态管理器需要做什么样的一种操作。拿以上例子来说,就是为了做一个切换table的操作,那么我就定义了这么一个action。data就是你做这个操作需要处理的一些数据等。

2、Reducers :

const reducer = function(state={"tableIndex":0}, action={}) {
        switch(action.type){
              //当发出type为changeTable的action对state的操作
              case "changeTable":
                    let backup = state;
                    backup["tableIndex"] = action.data;
                    return Object.assign({}, state,backup);
              default :
                    return Object.assign({}, state);
        }
}

以上例子就是一个reducer,它是一个会对不同action做出不同操作的函数。

如当我发出切换table的action时,就是把我们之前定义action的data传递给state下的tableIndex变量,用来告诉state,我要切换table的序号。

在没有任何操作情况下,我们返回初始的state。

我们不直接去改变state的值,而是返回一个新的对象,保持state的唯一性。缓存可以在这里做,后面会有叙述

3、Store:

var store = createStore(reducer);

这就是Store了,用来管理state的单一对象。其中有三个方法:

  • store.getState():获取state,如上,经过reducer已经返回了一个新的state,那么就可以用该函数获取;
  • store.dispatch(action):发出操作,更新state。action内有操作的类型,就可以出发不同的对state的更新;
  • store.subscribe(listener):监听变化,当state发生更新时,就可以在这个函数的回调中监听。

上述为基本redux的用法和含义,发出的操作也是同步的,如要更深入了解异步操作和对state更合理的逻辑管理,可以查看Middleware、combineReducers函数等,本文不再详述。

react-redux

讲完了基本的redux,那么理解和react结合就简单的多了。

在使用react-redux之前,别忘了下载该模块。

react-redux在redux的基础上,就关注两点:Providerconnect

1、Provider:

<Provider store={store}>
    <Router ref="router" history={hashHistory}>
        <Route path='/' component={Index}>
            <IndexRoute  component={MainPage}></IndexRoute>
        </Route>
    </Router>
</Provider>

Provider就是把我们用rudux创建的store传递到内部的其他组件。让内部组件可以享有这个store并提供对state的更新。

2、connect:

export default connect(mapStateToProps,mapDispatchToProps)(MainPage);

connect()一共有四个参数,但我这里只说基本的两个,mapStateToPropsmapDispatchToProps

  • mapStateToProps:简单来说,就是把状态绑定到组件的属性当中。我们定义的state对象有哪些属性,在我们组件的props都可以查阅和获取。

    const mapStateToProps = (state, ownProps) => {
          return {tableIndex:state.tableIndex}
    }
    

查看props

在props中,我们就看到了我们绑定的状态。

它的初值就是reducer默认返回state中的值。

  • mapDispatchToProps:在redux中介绍过,用store.dispatch(action)来发出操作,那么我们同样可以把这个方法封装起来,即绑定到我们的方法中。

    const mapDispatchToProps = (dispatch, ownProps) => {
        return {
            changeActive:(args)=>dispatch({type:"changeTable",data:args})
        }
    }
    

可以看到,这个方法return的就是一个dispatch函数,将该方法绑定到属性上,我们同样可以在props查看和调用。

查看props

这样,我们只要在组件中调用该属性中的方法,就可以发出一个特定的action,触发reducer对state进行更新。这里的reducer就是之前在redux中定义的reducer。

这时候state如果发生更新,因为我们已经把state也绑定到props中,那么会把这些新的props重新传递下去,组件会进行更新渲染,达到我们需要的目的。

如果需要缓存怎么办?

还记得我们定义的reducer么。我们只需要将最新的状态存起来(无论是sessionStorage、数据库还是其它),然后默认的state去取缓存过的状态进行初始化渲染即可。

 const reducer = function(state={"tableIndex":0}, action={}) {
        switch(action.type){
              //当发出type为changeTable的action对state的操作
              case "changeTable":
                    let backup = state;
                    backup["tableIndex"] = action.data;       
                    //定义新的state,用于存储                           
                    let newState = Object.assign({}, state,backup);
                    sessionStorage.setItem("state",JSON.stringify(newState));
                    return newState;
              default :
                    if(sessionStorage.getItem("state")){
                    //获取缓存过的state
                          return Object.assign({},JSON.parse(sessionStorage.getItem("state")));
                    }else{
                          return Object.assign({}, state);
                    }
        }
}

其实react-redux中还有许多可用配置的参数和方法。越是复杂的项目,用起来会越清晰。本文只是一些基本用法的梳理,更深的了解可访问:https://github.com/reactjs/react-redux 等其他在线资料。