Redux学习笔记

Posted 做枚温婉的妹纸吧哈哈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux学习笔记相关的知识,希望对你有一定的参考价值。

Redux

基本概念

store

store管理整颗状态树。状态树是一个大的对象,有一颗颗state节点构成。 它提供了dispatchgetstatesubscribe这些方法来管理整个状态。
store通过 createStore(reducer, initialState, middleware)来创建。
store.getState()返回state对象。

dispatch和action

状态不能直接修改,view需要通过store.dispatch方法来派发一个action,告知需要修改state的哪个部分。action是一个对象,必须包含type属性。可以通过action creator来生成action。

reducer(state=initialState, action)

当一个action派发后,会自动调用reducer函数进行state的修改,reducer内部也不能直接修改原state,需要返回一个新的state,目的是为了保证一个时刻,一个view对应的state是唯一的。reducer是一个函数,接收(state, action) 作为参数,可通过 state = initialState 方式进行state的初始化。

reducer的拆分:reducer本质上是返回一个新的state对象(树)。如果把所有的state更新写到一个reducer里,函数将会变得非常庞大,不利于维护。因此可以将reducer拆分成多个函数,每个函数只维护state树上的一个节点,最后合起来返回一个完整的state树。redux提供了combineReducers用来将多个拆分出来的reducer合成一个大的reducer

(1)state节点名和reducer函数同名:

(2)state节点名和reducer不同名:

参考:Redux中文文档

reducer是因为它和数组方法reducecallback参数类似:

Array.prototype.reduce(callback, initialValue).

callback方法的参数为:previousValue, currentValue, currentIndex, array
callback 上一次执行的结果作为下一次的previousValue.

再看看reducer函数reducer(previouseState, action)。这样看来是不是和arrayreduce很相似。

reducer是个纯函数,输入相同则输出相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。

可以通过Object.assign(, state, ...)来返回一个新的对象,或者采用ES7提案,对象扩展运算符...state, …。对于内部包含的引用类型,也是要返回一个新的数组或者对象(使用扩展运算符或者其他方式)。
参考:Redux中的reducer到底是什么,以及它为什么叫reducer?

subscribe

通过store.subscribe(listener)来设置每当state变化时需要执行的函数,传入render函数则是state变化后更新视图(listener可通过store.getState获得当前的state)。

模拟Store的实现:

可以看出当view触发状态变化的流程是:

Created with Raphaël 2.1.2 view触发状态改变 dispatch action 调用reducer更改state 调用subscribe注册的listener 更新view

在源码实现中,dispatch的时候调用了reducerlistener

redux适用场景

中间件

解决例如异步action等问题.具体参考Redux 入门教程(二):中间件与异步操作

redux-thunk

dispatch一个action是同步执行的,但有时候需要异步或者条件执行一个actionredux-thunk提供了一种方法,可以达到这个目的。此时的action creator返回的不是一个对象,而是一个方法,这个方法内部可以异步或者条件dispatch一个action
这个返回的thunk action creator接收dispatch, getState为参数。对于返回值,官网这样解释:

Any return value from the inner function will be available as the return value of dispatch itself. This is convenient for orchestrating an asynchronous control flow with thunk action creators dispatching each other and returning Promises to wait for each other’s completion

意思就是内部函数的返回值作为最外部dispatch 方法的返回值。
可参考官网例子,如何在内部方法里返回promise进行dispatch后的链式调用的。https://github.com/gaearon/redux-thunk
http://cn.redux.js.org/docs/advanced/AsyncActions.html

单向数据流

这意味着应用中所有的数据都遵循相同的生命周期,这样可以让应用变得更加可预测且容易理解。同时也鼓励做数据范式化,这样可以避免使用多个且独立的无法相互引用的重复数据。

react-redux

封装了在react中使用redux的一些API,使得使用更方便。需遵守其组件的拆分规则。

UI组件和容器组件

UI组件

容器组件

所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。状态管理交给容器组件。

主要API

connect

将用户定义的UI组件包装为一个容器组件。

const VisibleTodoList = connect(
    mapStateToProps,
    mapDispatchToProps
)(TodoList)

mapStateToProps(state, ownProps)

返回一个对象,组件props参数到state的映射:

const mapStateToProps = (state) => 
    return 
        todos: getVisibleTodos(state.todos, state.visibilityFilter)
    

返回对象Key值对应组件的一个props参数。

组件内部可以通过this.props.todos访问传入的state。组件会订阅store,当state改变,props也跟着改变,触发UI组件的重新渲染。ownProps是一个对象,里面包含自己通过组件传入的props,而不是state映射的props。如果connect不传入mapStateToProps,则UI组件不会订阅store,当state更新的时候,UI不会重新渲染。

mapDispatchToProps(dispatch, ownProps)

组件的参数propsstore.dispatch的映射。即组件内部怎么派发一个action。
有以下两种调用方式:
(1)函数

const mapDispatchToProps = (
    dispatch,
    ownProps
) => 
    return 
        onClick: () => 
            dispatch(
                type: 'SET_VISIBILITY_FILTER',
                filter: ownProps.filter
             );
        
     ;

函数返回一个对象,对象Key值对应组件的一个props参数,value是调用了dipatch的一个函数。

(2)对象

const mapDispatchToProps = 
    onClick: (filter) => 
        type: 'SET_VISIBILITY_FILTER',
        filter: filter
    ;

这种方式,键值为action creator。返回的action会由Redux自动发出。

Provider组件

使组件层级中的 connect() 方法都能够获得 Redux store. 实现原理是利用了context.

 <Provider store=store>
    <App />
  </Provider>,

以上是关于Redux学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

React+Redux学习笔记:React+Redux简易开发步骤

redux-form的学习笔记

redux-form的学习笔记

React 学习笔记总结

React 学习笔记总结

Redux 入门学习笔记 ① —— 基本概念及使用