微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

浅析Redux数据流

原文地址:https://github.com/YutHelloWo...

-- React Redux 数据流

通过这张流程图,我们可以更好的理解Redux和React直接数据如何流通,关系如何映射。

让我们一步步来了解图中的各个概念。

action & actionCreator

action creator 就是函数而已,负责构建一个 action (是的,action creator 这个名字已经很明显了)并返回它。通过几行简单的代码就可以解释清楚了!

const actionCreator = function () {
  return {
    type : 'AN_ACTION'
  }
}

一般约定 action 是一个拥有 type 属性的对象。

console.log(actionCreator())
//  { type: 'AN_ACTION' }

reducer

Reducer 函数只是一个函数,它接收应用程序的当前状态以及发生的 action,然后返回修改后的新状态(或者有人称之为归并后的状态)。Reducer 函数是 action 的订阅者。

const reducer = function (state = {},action) {
  console.log('reducer was called with state',state,'and action',action);

  return state;
}

Store

以上,action描述“发生了什么”,而reducer根据action来更新state。但是他们两者之间是如何关联的呢?

不用担心,Redux 会帮你把action和reducer连接起来。

我们把 Redux实例称为 store 并用以下方式创建:

import { createStore } from 'redux'

const store_0 = createStore(() => {})

注意:在createStore时,需要给它传入一个 reducer 函数

每当一个action发生时,Redux都能调用这个函数。往 createStore 传 Reducer 的过程就是给 Redux绑定 action处理函数(也就是Reducer)的过程。

接下来,试着在 Reducer 中打印一些 log

const reducer = function (...args) {
  console.log('Reducer was called with args',args)
}

const store_1 = createStore(reducer)
// 输出:Reducer was called with args [ undefined,{ type: '@@redux/INIT' } ]

我们没有dispatch(分发)任何action,但是reducer被调用了!这是由于初始化应用state的时候,Redux dispatch 了一个初始化的 action ({ type: '@@redux/INIT' })。reducer的入参为(state,action)。state还没有被初始化,自然为undefined

如何读取store中的state?

Redux为我们提供了store.getState()方法

import { createStore } from 'redux'

const reducer_2 = function (state = {},action) {
  console.log('reducer_2 was called with state',action)

  return state;
}

const store_2 = createStore(reducer_2)
// 输出: reducer_2 was called with state {} and action { type: '@@redux/INIT' }

console.log('store_2 state after initialization:',store_2.getState())
// 输出: store_2 state after initialization: {}

如何dispatch action?

我们需要使用store.dispatch(action)方法

// 接以上代码
const anAction = {
  type : 'AN_ACTION'
}
store_2.dispatch(anAction);
// 输出:reducer_2 was called with state {} and action { type: 'AN_ACTION' }

combineReducers

combineReducer用于合并Reducers,并且合并对应的State。

const userReducer  = function (state = {},action) {
  console.log('userReducer was called with state',action)

  switch (action.type) {
    // etc.
    default:
      return state;
  }
}
const itemsReducer = function (state = [],action) {
  console.log('itemsReducer was called with state',action)

  switch (action.type) {
    // etc.
    default:
      return state;
  }
}
import { createStore,combineReducers } from 'redux'

const reducer = combineReducers({
  user  : userReducer,items : itemsReducer
})

// 输出:
// userReducer was called with state {} and action { type: '@@redux/INIT' }
// userReducer was called with state {} and action { type: '@@redux/PROBE_UNKNowN_ACTION_9.r.k.r.i.c.n.m.i' }
// itemsReducer was called with state [] and action { type: '@@redux/INIT' }
// itemsReducer was called with state [] and action { type: '@@redux/PROBE_UNKNowN_ACTION_4.f.i.z.l.3.7.s.y.v.i' }

var store_0 = createStore(reducer)

// 输出:
// userReducer was called with state {} and action { type: '@@redux/INIT' }
// itemsReducer was called with state [] and action { type: '@@redux/INIT' }

console.log('store_0 state after initialization:',store_0.getState())
// 输出:
// store_0 state after initialization: { user: {},items: [] }

回过头来看看文章开头的数据流向图

View组件通过click等事件,dispatch一个(actionCreator返回的)action,通过Store把当前状态state和action传递给订阅者reducer函数,reducer返回一个新的状态存储在Store中,Store又把新的State传递给View组件触发组件更新。

为了将Redux和React联系到一起。就需要用到React-Redux这个库。

import { connect } from 'react-redux'
const containerComponent = connect(mapStatetoProps,mapdispatchToProps)(presentationalComponent)

简单来说,mapStatetoProps和mapdispatchToProps就是分别把Redux的state,和dispatch(action)映射到React组件中作为props。connect将展示组件(presentationalComponent)封装成高阶的容器组件(containerComponent)。state的更新意味着props更新。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...