react-redux

2018-08-21  本文已影响0人  进击的前端_风笑影

redux有5个接口

createStore
combineReducers
bindActionCreators
applyMiddleware
compose

一. createStore

createStore函数有三个参数

reducer:reducer是一个函数,该函数会返回一个全新的state,而state则保存了所有的数据
preloadedState:初始state
enhancer:这个参数特别有意思,如果该enhancer参数存在的话,会将当前的createStore
函数作为参数传入enhancer函数,并且,enhancer执行之后得到一个新函数,该新函数其实
就是一个加强版的createStore函数,新的函数会把之前的reducer和preloadeState作为参数
传入并执行。这个enhancer参数为redux中间件提供了入口。

createStore 的函数的作用就是生成一个 store 对象,这个对象具有5个方法:

return {
    dispatch,  // 传入 action,调用 reducer 及触发 subscribe 绑定的监听函数
    subscribe,
    getState,
    replaceReducer,  // 用新的 reducer 代替当前的 reducer,使用不多
    [$$observable]: observable
  }

compose 函数则是 applyMiddleware 函数的核心,其会形成串联的函数调用关系,用于增强 dispatch 方法。

二. applyMiddleware

applyMiddleware方法主要是对redux的dispacth方法进行封装

而 applyMiddleware 函数的作用就是对 store.dispatch 方法进行增强和改造,使得在发出 Action 和执行 Reducer 之间添加其他功能。

单一的state是存储在store中,当要对state进行更新的时候,首先要发起一个action(通过dispatch函数),action的作用就是相当于一个消息通知,用来描述发生了什么(比如:增加一个Todo),然后reducer会根据action来进行对state更新,这样就可以根据新的state去渲染View。

当然上面仅仅是发生同步Action的情况下,如果是Action是异步的(例如从服务器获取数据),那么情况就有所不同了,必须要借助Redux的中间件Middleware。

根据官方的解释,Redux中间件在发起一个action至action到达reducer的之间,提供了一个第三方的扩展。本质上通过插件的形式,将原本的action->redux的流程改变为action->middleware1->middleware2-> ... ->reducer,通过改变数据流,从而实现例如异步Action、日志输入的功能。

使用方式

const store = applyMiddleware(...middlewares)(createStore)(reducer, initialState)

首先我们举例不使用中间件Middleware创建store:

import rootReducer from './reducers'
import {createStore} from 'redux'

let store =  createStore(rootReducer);

那么使用中间件的情况下(以redux-logger举例),创建过程如下:

import rootReducer from './reducers'
import {createStore,applyMiddleware} from 'redux'
import createLogger from 'redux-logger'

const loggerMiddleware = createLogger();
let store = applyMiddleware(loggerMiddleware)(createStore)(rootReducer);

三. combineReducers

随着应用变得复杂,需要对 reducer 函数 进行拆分,拆分后的每一块独立负责管理 state 的一部分。

那么问题来了,这么拆分如何使用createStore去创建store呢,毕竟createStore只能传一个Reducer参数。而且createStore只能调用一次。

在redux中提供了一个combineReducers的方法,用来组合我们的Reducer。

const mainReducer = combineReducers({
    homeReducer,
    profileReducer
})
let store = createStore(mainReducer);

示例

reducers/todos.js

export default function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([action.text])
  default:
    return state
  }
}

reducers/counter.js

export default function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT':
    return state + 1
  case 'DECREMENT':
    return state - 1
  default:
    return state
  }
}

reducers/index.js

import { combineReducers } from 'redux'
import todos from './todos'
import counter from './counter'

export default combineReducers({
  todos,
  counter
})

App.js

import { createStore } from 'redux'
import reducer from './reducers/index'

let store = createStore(reducer)
console.log(store.getState())
// {
//   counter: 0,
//   todos: []
// }

store.dispatch({
  type: 'ADD_TODO',
  text: 'Use Redux'
})
console.log(store.getState())
// {
//   counter: 0,
//   todos: [ 'Use Redux' ]
// }

四. bindActionCreators

上一篇下一篇

猜你喜欢

热点阅读