redux詳解

redux介紹
css

學習文檔英文文檔中文文檔Githubvue

redux是什麼react

redux是一個獨立專門用於作狀態管理的JS(不是react插件庫),它能夠用在react, angular, vue等項目中, 但基本與react配合使用git

做用: 集中式管理react應用中多個組件共享的狀態github

redux工做流程ajax

將會把這個過程比擬成圖書館的一個流程來幫助理解chrome

Action Creator(具體借書的表達) :想借書的人向圖書館管理員說明要借的書的那句話npm

Store(圖書館管理員) :負責整個圖書館的管理。是Redux的核心編程

Reducers(圖書館管理員的小本本) :管理員須要藉助Reducer(圖書館管理員的小本本)來記錄。redux

React Component(借書的人 ) :須要借書的人 

借書的人(ReactComponent)說了一句話(Action Creator)向圖書館管理員(Store)借一本書,但是圖書館管理員年紀大了啊記不住啊,便掏出了本身的小本本(Reducers)。看了看知道了那本書有沒有,在哪,怎麼樣。這樣一來管理員就拿到了這本書,再把這本書交給了借書人

翻譯過來就是:組件想要獲取State, 用ActionCreator建立了一個請求交給Store,Store藉助Reducer確認了該State的狀態,Reducer返回給Store一個結果,Store再把這個State轉給組件。

 

 

 

 

什麼狀況下須要使用redux

整體原則: 能不用就不用, 若是不用比較吃力才考慮使用,某個組件的狀態,須要共享,某個狀態須要在任何地方均可以拿到

一個組件須要改變全局狀態,一個組件須要改變另外一個組件的狀態

 

 

 

不用redux的方式實現更改狀態

首先咱們建立一個項目,建立應用目錄和文件以下

將建立的main.js組件在App.js入口組件中引入

import React from 'react';
import './App.css';

import Main from './views/main/main'
function App() {
  return (
    <div className="App">
      <Main/>
    </div>
  );
}

export default App;

而且在main.js這個組件中實現以下的組件

import React from 'react';
import './main.css';

class Main extends React.Component{
  state = {
    count: 0
  }
  increment = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1 // 由於的到的是字符串因此乘以1隱式轉換成number
    // 2. 讀取本來state中的count狀態,而且計算新的count
    const count = this.state.count + number
    // 3. 更新state的count狀態
    this.setState({
      count // 完整的寫法式count: count,由於名字相同因此直接寫一個count便可
    })
  }
  decrement = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態,而且計算新的count
    const count = this.state.count - number
    // 3. 更新state的count狀態
    this.setState({
      count
    })
  }
  incrementIfOdd = ()=> {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.state.count
    // 3. 判斷當前狀態若是式奇數才更新
    if (count%2 === 1) {
      // 4. 更新state的count狀態
      this.setState({
        count: count + number
      })
    }

  }
  incrementAsync =() => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.state.count

    // 啓動延時定時器
    setTimeout(() => {
      // 3. 異步更新state的count狀態
      this.setState({
        count: count + number
      })
    },1000)
  }
  render() {
    const {count} = this.state
    return (
      <div className="App">
        <p>click {count} times</p>
        <div>
          <select ref={select => this.select = select}>
            <option value='1'>1</option>
            <option value='2'>2</option>
            <option value='3'>3</option>
          </select>
          <button onClick={this.increment}>+</button>
          <button onClick={this.decrement}>-</button>
          <button onClick={this.incrementIfOdd}>increment if odd</button>
          <button onClick={this.incrementAsync}>increment async</button>
        </div>
      </div>
    );
  }
}

export default Main;

以上咱們使用正常的方式實現了上圖中的效果,接下來改形成redux的方式去實現,先來看看redux的核心API

 

 

redux的核心API

store

就是保存數據的地方,你能夠把它當作一個數據,整個應用智能有一個store,Redux提供createStore這個函數,用來生成Store

state

就是store裏面存儲的數據,store裏面能夠擁有多個state,Redux規定一個state對應一個View,只要state相同,view就是同樣的,反過來也是同樣的,能夠經過store.getState( )獲取

Action

state的改變會致使View的變化,可是在redux中不能直接操做state也就是說不能使用this.setState來操做,用戶只能接觸到View。在Redux中提供了一個對象來告訴Store須要改變state。

Action是一個對象其中type屬性是必須的,表示Action的名稱,其餘的能夠根據需求自由設置。

store.dispatch( )

store.dispatch( )是view觸發Action的惟一辦法,store.dispatch接收一個Action做爲參數,將它發送給store通知store來改變state。

Reducer

Store收到Action之後,必須給出一個新的state,這樣view纔會發生變化。這種state的計算過程就叫作Reducer。Reducer是一個純函數,他接收Action和當前state做爲參數,返回一個新的state

 

 

redux的基本使用

首先下載安裝redux的依賴包

npm install --save redux

項目根目錄建立一個專門管理redux的文件夾,而且建立action-types.js文件,用於管理action對象的type常量名稱模塊

// action對象的type常量名稱模塊

export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

而後再redux目錄中建立reducer函數的模塊:reducers.js

/*包含n個reducer函數的模塊*/

// 根據老的state和指定action, 處理返回一個新的state

import {INCREMENT, DECREMENT} from './action-types'

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

而後在項目入口文件index.js中引入這個reducer函數counter,而且將這個counter放到createStore方法中返回一個store對象

store對象的做用是redux庫最核心的管理對象,它內部維護着state和reducer,核心方法有getState(),dispatch(action),subscribe(listener)

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux';
import {counter} from './redux/reducers';

// 建立一個store對象
// createStore()的做用是建立包含指定reducer的store對象
const store = createStore(counter); // 內部會第一次調用reduer函數獲得初始state

console.log(store);//store對象

ReactDOM.render(<App store={store} />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

而後在應用組件中使用(須要將store經過props傳遞到須要使用的組件中)

import React from 'react';
import './App.css';
import PropTypes from 'prop-types'

import Main from './views/main/main'
class App extends React.Component {
  static propTypes = {
    store: PropTypes.object.isRequired,
  }

  render() {
    return (
      <div className="App">
        <Main store={this.props.store}/>
      </div>
    );
  }
}

export default App;
import React from 'react';
import './main.css';
import PropTypes from "prop-types";
import {INCREMENT, DECREMENT} from '../../redux/action-types'

class Main extends React.Component{
  static propTypes = {
    store: PropTypes.object.isRequired,
  }
  increment = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1 // 由於的到的是字符串因此乘以1隱式轉換成number

    // 2. 調用store的方法更新狀態
    this.props.store.dispatch({
      type: INCREMENT,
      data: number
    })
  }
  decrement = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 2. 調用store的方法更新狀態
    this.props.store.dispatch({
      type: DECREMENT,
      data: number
    })
  }
  incrementIfOdd = ()=> {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.props.store.getState()
    // 3. 判斷當前狀態若是式奇數才更新
    if (count%2 === 1) {
      // 4. 調用store的方法更新狀態
      this.props.store.dispatch({
        type: INCREMENT,
        data: number
      })
    }
  }
  incrementAsync =() => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1// 啓動延時定時器
    setTimeout(() => {
      // 2. 調用store的方法更新狀態
      this.props.store.dispatch({
        type: INCREMENT,
        data: number
      })
    },1000)
  }
  render() {
    const count = this.props.store.getState()
    return (
      <div className="App">
        <p>click {count} times</p>
        <div>
          <select ref={select => this.select = select}>
            <option value='1'>1</option>
            <option value='2'>2</option>
            <option value='3'>3</option>
          </select>
          <button onClick={this.increment}>+</button>
          <button onClick={this.decrement}>-</button>
          <button onClick={this.incrementIfOdd}>increment if odd</button>
          <button onClick={this.incrementAsync}>increment async</button>
        </div>
      </div>
    );
  }
}

export default Main;

subscribe(listener),狀態更新了以後須要調用這個方法來刷新

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux';
import {counter} from './redux/reducers';

// 建立一個store對象
// createStore()的做用是建立包含指定reducer的store對象
const store = createStore(counter); // 內部會第一次調用reduer函數獲得初始state

console.log(store);//store對象

function render () {
  ReactDOM.render(<App store={store} />, document.getElementById('root'));
}
render() // 初始化渲染

store.subscribe(render) // 訂閱監聽(store中的狀態變化了就會自動調用進行重繪)

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

能夠把要執行的行爲對象action單獨抽離出來一個模塊,使用工廠函數的方式(官方推薦的寫法),在redux文件夾中建立一個actions.js

/*action creator模塊*/
import {INCREMENT, DECREMENT} from './action-types'

export const increment = number => ({type: INCREMENT, data: number})
export const decrement = number => ({type: DECREMENT, data: number})
import React from 'react';
import './main.css';
import PropTypes from "prop-types";
import * as actions from '../../redux/actions'

class Main extends React.Component{
  static propTypes = {
    store: PropTypes.object.isRequired,
  }
  increment = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1 // 由於的到的是字符串因此乘以1隱式轉換成number

    // 2. 調用store的方法更新狀態
    this.props.store.dispatch(actions.increment(number))
  }
  decrement = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 2. 調用store的方法更新狀態
    this.props.store.dispatch(actions.decrement(number))
  }
  incrementIfOdd = ()=> {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.props.store.getState()
    // 3. 判斷當前狀態若是式奇數才更新
    if (count%2 === 1) {
      // 4. 調用store的方法更新狀態
      this.props.store.dispatch(actions.increment(number))
    }
  }
  incrementAsync =() => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 啓動延時定時器
    setTimeout(() => {
      // 2. 調用store的方法更新狀態
      this.props.store.dispatch(actions.increment(number))
    },1000)
  }
  render() {
    const count = this.props.store.getState()
    return (
      <div className="App">
        <p>click {count} times</p>
        <div>
          <select ref={select => this.select = select}>
            <option value='1'>1</option>
            <option value='2'>2</option>
            <option value='3'>3</option>
          </select>
          <button onClick={this.increment}>+</button>
          <button onClick={this.decrement}>-</button>
          <button onClick={this.incrementIfOdd}>increment if odd</button>
          <button onClick={this.incrementAsync}>increment async</button>
        </div>
      </div>
    );
  }
}

export default Main;

還有一個就是將store搬到一個獨立的模塊中,在redux文件夾建立一個store.js的文件

import {createStore} from 'redux';
import {counter} from './reducers';

// 建立一個store對象
// createStore()的做用是建立包含指定reducer的store對象
const store = createStore(counter); // 內部會第一次調用reduer函數獲得初始state
console.log(store);//store對象

export default store

修改index.js項目入口文件

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './redux/store'

function render () {
  ReactDOM.render(<App store={store} />, document.getElementById('root'));
}
render() // 初始化渲染

store.subscribe(render) // 訂閱監聽(store中的狀態變化了就會自動調用進行重繪)

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

 

 

 

react-redux

上面使用redux,有一些小的問題就是:reduxreact組件的代碼耦合度過高,編碼不夠簡潔,那麼就有了一個插件react-redux

react-redux:一個react插件庫,專門用來簡化react應用中使用redux

React-Redux將全部組件分紅兩大類:

UI組件:只負責 UI 的呈現,不帶有任何業務邏輯,經過props接收數據(通常數據和函數),不使用任何 Redux API,通常保存在components文件夾下

容器組件:負責管理數據和業務邏輯,不負責UI的呈現,使用 Redux API,通常保存在containers文件夾下

React-Redux相關API

Provider:這是一個組件,將這個組件包裹着App.js組件讓全部組件均可以獲得state數據

<Provider store={store}>
    <App />
</Provider>

connect():用於包裝 UI 組件生成容器組件,就是用於react組件和redux之間的鏈接

mapStateToprops():將外部的數據(即state對象)轉換爲UI組件的標籤屬性

mapDispatchToProps():將分發action的函數轉換爲UI組件的標籤屬性,簡潔語法能夠直接指定爲actions對象或包含多個action方法的對象

import { connect } from 'react-redux'
connect(
  mapStateToprops,
  mapDispatchToProps
)(Counter)

使用react-redux

首先須要下載安裝依賴包

npm install --save react-redux

修改index.js項目入口文件

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './redux/store'
import {Provider} from 'react-redux'

ReactDOM.render((
  <Provider store={store} >
    <App/>
  </Provider>
), document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

sotre也不須要一層層的傳遞了

import React from 'react';
import './App.css';

import Main from './views/main/main'
class App extends React.Component {
  render() {
    return (
      <div className="App">
        <Main/>
      </div>
    );
  }
}

export default App;

在應用組件中使用react-redux的API方法connect()來跟store進行鏈接

import React from 'react';
import './main.css';
import PropTypes from "prop-types";
import { connect } from 'react-redux';

import {increment, decrement} from '../../redux/actions';

class Main extends React.Component{
  static propTypes = {
    count: PropTypes.number.isRequired,
    increment: PropTypes.func.isRequired,
    decrement: PropTypes.func.isRequired
  }
  increment = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1 // 由於的到的是字符串因此乘以1隱式轉換成number

    // 2. 調用store的方法更新狀態
    this.props.increment(number)
  }
  decrement = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 2. 調用store的方法更新狀態
    this.props.decrement(number)
  }
  incrementIfOdd = ()=> {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.props.count
    // 3. 判斷當前狀態若是式奇數才更新
    if (count%2 === 1) {
      // 4. 調用store的方法更新狀態
      this.props.increment(number)
    }
  }
  incrementAsync =() => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 啓動延時定時器
    setTimeout(() => {
      // 2. 調用store的方法更新狀態
      this.props.increment(number)
    },1000)
  }
  render() {
    const {count} = this.props
    return (
      <div className="App">
        <p>click {count} times</p>
        <div>
          <select ref={select => this.select = select}>
            <option value='1'>1</option>
            <option value='2'>2</option>
            <option value='3'>3</option>
          </select>
          <button onClick={this.increment}>+</button>
          <button onClick={this.decrement}>-</button>
          <button onClick={this.incrementIfOdd}>increment if odd</button>
          <button onClick={this.incrementAsync}>increment async</button>
        </div>
      </div>
    );
  }
}

// connect是一個函數須要接收一個參數是組件類型(也就是一個對象),執行以後返回的仍是一個函數,而且返回新的組件
export default connect(
  state => ({count: state}),
  {increment, decrement}
)(Main);

這樣咱們就把react-redux給使用上了,還能夠在進一步優化就是將connect和組件分離出來,UI組件: 不包含任何redux API

import React from 'react';
import './main.css';
import PropTypes from "prop-types";

class Main extends React.Component{
  static propTypes = {
    count: PropTypes.number.isRequired,
    increment: PropTypes.func.isRequired,
    decrement: PropTypes.func.isRequired
  }
  increment = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1 // 由於的到的是字符串因此乘以1隱式轉換成number

    // 2. 調用store的方法更新狀態
    this.props.increment(number)
  }
  decrement = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 2. 調用store的方法更新狀態
    this.props.decrement(number)
  }
  incrementIfOdd = ()=> {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.props.count
    // 3. 判斷當前狀態若是式奇數才更新
    if (count%2 === 1) {
      // 4. 調用store的方法更新狀態
      this.props.increment(number)
    }
  }
  incrementAsync =() => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 啓動延時定時器
    setTimeout(() => {
      // 2. 調用store的方法更新狀態
      this.props.increment(number)
    },1000)
  }
  render() {
    const {count} = this.props
    return (
      <div className="App">
        <p>click {count} times</p>
        <div>
          <select ref={select => this.select = select}>
            <option value='1'>1</option>
            <option value='2'>2</option>
            <option value='3'>3</option>
          </select>
          <button onClick={this.increment}>+</button>
          <button onClick={this.decrement}>-</button>
          <button onClick={this.incrementIfOdd}>increment if odd</button>
          <button onClick={this.incrementAsync}>increment async</button>
        </div>
      </div>
    );
  }
}

export default Main

建立containters文件夾而且建立一個js文件(包含Main組件的容器組件

import React from 'react';
import { connect } from 'react-redux';

import {increment, decrement} from '../redux/actions';
import Main from '../views/main/main'

// connect是一個函數須要接收一個參數是組件類型(也就是一個對象),執行以後返回的仍是一個函數,而且返回新的組件
export default connect(
  state => ({count: state}),
  {increment, decrement}
)(Main);
import React from 'react';
import './App.css';

import Main from './containters/main'
class App extends React.Component {
  render() {
    return (
      <div className="App">
        <Main/>
      </div>
    );
  }
}

export default App;

這樣就完成了react-redux的使用,可是也有一個問題就是redux默認是不能進行異步處理的, 應用中又須要在redux中執行異步任務(ajax, 定時器)

怎麼樣讓redux支持異步操做,請看下面:redux異步編程

 

 

 

 

redux異步編程

下載redux插件(異步中間件)

npm install --save redux-thunk

而後下redux文件夾的store.js文件中引入

import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import {counter} from './reducers';

// 建立一個store對象
// createStore()的做用是建立包含指定reducer的store對象
const store = createStore(
  counter,
  applyMiddleware(thunk)  // 應用上異步中間件
);

export default store

在actions.js中添加一個異步操做的方法

/*action creator模塊*/
import {INCREMENT, DECREMENT} from './action-types'

export const increment = number => ({type: INCREMENT, data: number})
export const decrement = number => ({type: DECREMENT, data: number})
export const incrementAsync = number => {
  return dispatch => {
    setTimeout(() => {
      dispatch(increment(number))
    }, 1000)
  }
}

在connect()把這個action方法加進來

import React from 'react';
import { connect } from 'react-redux';

import {increment, decrement, incrementAsync} from '../redux/actions';
import Main from '../views/main/main'

// connect是一個函數須要接收一個參數是組件類型(也就是一個對象),執行以後返回的仍是一個函數,而且返回新的組件
export default connect(
  state => ({count: state}),
  {increment, decrement, incrementAsync}
)(Main);

在應用組件中經過props進行調用這個action方法

import React from 'react';
import './main.css';
import PropTypes from "prop-types";

class Main extends React.Component{
  static propTypes = {
    count: PropTypes.number.isRequired,
    increment: PropTypes.func.isRequired,
    decrement: PropTypes.func.isRequired,
    incrementAsync: PropTypes.func.isRequired
  }
  increment = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1 // 由於的到的是字符串因此乘以1隱式轉換成number

    // 2. 調用store的方法更新狀態
    this.props.increment(number)
  }
  decrement = () => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 2. 調用store的方法更新狀態
    this.props.decrement(number)
  }
  incrementIfOdd = ()=> {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1
    // 2. 讀取本來state中的count狀態
    const count = this.props.count
    // 3. 判斷當前狀態若是式奇數才更新
    if (count%2 === 1) {
      // 4. 調用store的方法更新狀態
      this.props.increment(number)
    }
  }
  incrementAsync =() => {
    // 1. 讀取select中的值(選擇增長的數量)
    const number = this.select.value*1

    // 2. 調用store的方法更新狀態
    this.props.incrementAsync(number)
  }
  render() {
    const {count} = this.props
    return (
      <div className="App">
        <p>click {count} times</p>
        <div>
          <select ref={select => this.select = select}>
            <option value='1'>1</option>
            <option value='2'>2</option>
            <option value='3'>3</option>
          </select>
          <button onClick={this.increment}>+</button>
          <button onClick={this.decrement}>-</button>
          <button onClick={this.incrementIfOdd}>increment if odd</button>
          <button onClick={this.incrementAsync}>increment async</button>
        </div>
      </div>
    );
  }
}

export default Main

 

 

 

 

使用上redux調試工具

首先安裝chrome瀏覽器插件(直接在谷歌應用商店搜索,而後點擊安裝)

而後在項目中下載工具依賴包

npm install --save-dev redux-devtools-extension

修改項目中的建立store的代碼中加入這個插件

import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension'
import {counter} from './reducers';

// 建立一個store對象
// createStore()的做用是建立包含指定reducer的store對象
const store = createStore(
  counter,
  composeWithDevTools(applyMiddleware(thunk))  // 應用上異步中間件
);

export default store

 

 

 

Redux源碼

let createStore = (reducer) => {
    let state;
    //獲取狀態對象
    //存放全部的監聽函數
    let listeners = [];
    let getState = () => state;
    //提供一個方法供外部調用派發action
    let dispath = (action) => {
        //調用管理員reducer獲得新的state
        state = reducer(state, action);
        //執行全部的監聽函數
        listeners.forEach((l) => l())
    }
    //訂閱狀態變化事件,當狀態改變發生以後執行監聽函數
    let subscribe = (listener) => {
        listeners.push(listener);
    }
    dispath();
    return {
        getState,
        dispath,
        subscribe
    }
}
let combineReducers=(renducers)=>{
    //傳入一個renducers管理組,返回的是一個renducer
    return function(state={},action={}){
        let newState={};
        for(var attr in renducers){
            newState[attr]=renducers[attr](state[attr],action)

        }
        return newState;
    }
}
export {createStore,combineReducers};
相關文章
相關標籤/搜索