redux小记

Posted diyigechengxu

tags:

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

Redux 设计和使用的三大原则:

  1. 单一数据源:

    一个应用永远只有唯一的数据源。使用单一数据源的好处在于整个应用状态都保存在一个对象中,这样我们随时可以 6提取出整个应用的状态进行持久化(比如实现一个针对整个应用的即时保存功能)。此外,这样 的设计也为服务端渲染提供了可能。工具函数combineReducers 可解决该数据源对象过于庞大的问题

  2. 状态是只读的:

    定义一个 reducer, 它的功能是根据当前触发的 action 对当前应用的状态(state)进行迭代,这里我们并没有直接修改应用的状态,而是返回了一份全新的状态。Redux 提供的 createStore 方法会根据 reducer 生成 store。最后,我们可以利用 store. dispatch方法来达到修改状态的目的。

  3. 状态修改均由纯函数完成

    Redux 利用每次新返回的状态生成酷炫的时间旅行(time travel)调试方式,让跟踪每一次因为触 发 action 而改变状态的结果成为了可能。

 

通过 createStore 方法创建的 store 是一个对象,包含以下方法。

? getState():获取 store 中当前的状态。
? dispatch(action):分发一个 action,并返回这个 action,这是唯一能改变 store 中数据的方式。

? subscribe(listener):注册一个监听者,它在 store 发生变化时被调用。  

 

<Provider/> 接受一个 store 作为props,它是整个 Redux 应用的顶层组件,而 connect() 提供了在整个 React 应用的任意组件中获取 store 中数据的功能。

  

redux-middleware:

  import compose from ‘./compose‘;

  

  let newStore = applyMiddleware(mid1, mid2, mid3, ...)(createStore)(reducer, null);//创建一个普通的 store

  export default function applyMiddleware(...middlewares) {//applyMiddleware 的结构也是一个多层 currying 的函数。借助 compose,applyMiddleware 可以用来和其他插件加强 createStore 函数:

    return (next) => (reducer, initialState) => {

      let store = next(reducer, initialState);//利用 createStore 和 reducer 创建了一个 store

      let dispatch = store.dispatch;
      let chain = [];

      var middlewareAPI = {
        getState: store.getState,
        dispatch: (action) => dispatch(action),

      };//store 的 getState方法和 dispatch 方法又分别被直接和间接地赋值给 middlewareAPI 变量 store


      chain = middlewares.map(middleware => middleware(middlewareAPI));//middleware 带着 middlewareAPI 这个参数分别执行一遍。执行完后,获得 chain数组,保存的对象是第二个箭头函数返回的匿名函数

      dispatch = compose(...chain)(store.dispatch);//将 chain 中的所有匿名函数,组装成一个新的函数,即新的 dispatch。当新 dispatch 执行时,数组内middleware从右到左依次执行

      return { ...store,
          dispatch,

      };

    }

  }

 

  logger middleware 的实现:

  export default store => next => action => {//applyMiddleware 会对 logger 这 个 middleware 进行层层调用,动态地将 store 和 next 参数赋值。

    console.log(‘dispatch:‘, action);

    typeof action === ‘function‘ ? action(store.dispatch, store.getState) : next(action)//判断 action 是否是函数。如果是,则执行 action,否则继续传递 action 到下 一个 middleware。

    console.log(‘finish:‘, action);

   }

 

  redux-saga: 采用generator,代替了async、await、promise等

 

  react-router-redux:

    对于前端应用来说,路由状态(当前切换到了哪个页面,当前页面的参数 有哪些,等等)也是应用状态的一部分。在很多情况下,我们的业务逻辑与路由状态有很强的关 联关系。比如,最常见的一个列表页中,分页参数、排序参数可能都会在路由中体现,而这些参 数的改变必然导致列表中的数据发生变化。因此,当我们采用 Redux 架构时,所有的应用状态必须放在一个单一的 store 中管理,路由 状态也不例外。而这就是 React Router Redux 为我们实现的主要功能。

    对 Redux 的 store 进行一些增强,以便分发的 action 能被正确识别

    

    import { browserHistory } from ‘react-router‘;

    import { routerMiddleware } from ‘react-router-redux‘;

    const middleware = routerMiddleware(browserHistory);

    const store = createStore(

      reducers,

      applyMiddleware(middleware)

    );

    

    可以用 store.dispatch 来分发一个路由变动的 action 了:

    import { push } from ‘react-router-redux‘;

    // 切换路由到 /home store.dispatch(push(‘/home‘));

 

高阶 reducer 主要通过下面 3 点来增强reducer:高阶 reducer 就是指将 reducer 作为参数或者返回值的函数

? 能够处理额外的 action;
? 能够维护更多的 state;
? 将不能处理的 action 委托给原始 reducer 处理。

createStore 的函数签名:

export default function createStore(reducer, initialState, enhancer) { // ...}

createStore 中的第二个参数不仅扮演着 initialState 的角色。如 果我们传入的第二个参数是函数类型,那么 createStore 会认为你忽略了 initialState 而传入了 一个 enhancer。

如果我们传入了一个有效的enhancer,createStore会返回enhancer(createStore)(reducer, initialState) 的调用结果,这是常见的高阶函数调用方法。在这个调用中,enhancer 接受createStore 作为参数,

对 createStore 的能力进行增强,并返回增强后的 createStore。然后再 将 reducer 和 initialState 作为参数传给增强后的 createStore,最终得到生成的 store。

var currentReducer = reducer

var currentState = initialState

var listeners = []
var isDispatching = false

function getState() {

  return currentState//getState 方法用于返回当前状态。

}

dispatch---将当前的状态和 action 传给当前的reducer,用于生成最新的 state。在得到新的状态后,依次调用所有的监听器,通知状态的变更。

需要注意的是,我们在通知监听器变更发生时,并没有将最新的状态作为参数传递给这些监听器。这是因为在监听器中,我们可以直接调用 store.getState() 方法拿到最新的状态。

 

React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)。

React-Redux 提供connect方法,用于从 UI 组件生成容器组件。connect的意思,就是将这两种组件连起来。

connect 函数本身返回名为 wrapWithConnect 的函数,而这个函数才是真正用来 装饰 React 组件的。而在我们装饰一个 React 组件时,

其实就是把组件在 Connect 类的 render 方 法中进行渲染,并获取 connect 中传入的各种额外数据。

connect 函数如果传入mapStateToProps,则会store.subscribe()监听state变化

Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。它的原理是React组件的context属性

class Provider extends Component {

  getChildContext() {

    return {store: this.props.store}

  }

  render() {

    return this.props.children;

  }

}

子组件就可以从context拿到store

  

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

json React / Redux片段

react小记

“ES7 React/Redux/GraphQL/React-Native 片段”不适用于 javascript 文件。除了安装它,我还需要配置其他东西吗?

react 中的 redux 和react-redux的区别分析

react-router 从 v3 版本升到 v4 版本,升级小记

提供商无法访问redux商店