React我的入門總結《六》

簡介

此次要總結的是對 storereducer 的拓展,好比發送異步的 action 操做,還有一個就是對多個 reducer 的管理。css

首先來總結一下 react-redux 的使用:react

1. 下載 react-reduxredux 到項目中。

2. 引入 createStore 而且建立 store

<!-- reducer -->
function handleUser(state = [], action) {
  switch (action.type) {
    case 'ADD_USER':
      state.push(action.user)
      return [...state];
    case 'DELETE_USER':
      state.splice(action.payload, 1);
      return [...state];
    default:
      return state
  }
}
export { handleUser }; 

<!-- store -->
import { createStore } from 'redux';
import { handleUser } from '../Reducer/handleUser';

const store = createStore(handleUser);
export { store };
複製代碼

3. 在 index.js 引入 store ,而且引入 Provider 而且將 store 傳遞給它。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './Redux/Store/store';
import * as serviceWorker from './serviceWorker';
import './assets/_reset.scss';

// 引入頁面
import { UserContainer } from './Pages/UserContainer';

ReactDOM.render(
  <Provider store={ store }>
    <UserContainer />
  </Provider>,
  document.getElementById('root')
)
複製代碼

4. 在 UI組件 中使用 connect 獲取當前狀態和使用 dispatch 發送 action

<!-- action -->
const addUser = (user) => ({
  type: 'ADD_USER',
  user: user
})
const deleteUser = (index) => ({
  type: 'DELETE_USER',
  index: index
})
export { addUser, deleteUser };


<!-- pages -->
import { addUser, deleteUser } from '../Redux/Action/addUserData';
const mapStateToProps = (state) => {
  return {
    userList: userList
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    addUserData: (user) => {
      return dispatch(addUser(user))
    },
    deleteUserData: (index) => {
      return dispatch(deleteUser(index))
    }
  }
}

UserContainer = connect(mapStateToProps, mapDispatchToProps)(UserContainer);
複製代碼

以上就是 react-redux 的使用,下面繼續拓展其餘使用方式。redux


combineReducers

combineReducersredux 提供的一個方法,調用這個方法而且傳入多個 reducer ,而後對這些 reducer 進行管理:promise

import { combineReducers } from 'redux';
import { handleUser } from './handleUser';
<!-- 寫法一 -->
const chatReducer = combineReducers({
  userList: handleUser,
  <!-- ...這裏能夠寫更多 reducer -->
})

<!-- 寫法二 -->
const chatReducer = combineReducers({
  handleUser,
  <!-- ...這裏能夠寫更多 reducer -->
})

export { chatReducer };
複製代碼

上面的 combineReducers 傳入的對象有兩個寫法,可是每一個寫法最終呈現的名字必需要與 state 同樣:bash

const mapStateToProps = (state) => {
  return {
    <!-- 這時 state 返回的是一個對象,裏面返回各個 reducer 返回的 state -->
    userList: state.userList
  }
}
複製代碼

還有一點就是 store 設置默認值的問題。app

<!-- 使用 combineReducers 以前-->
const store = createStore(
  handleUser,
  state
)

<!-- 使用 combineReducers 以後-->
const store = createStore(
  chatReducer,
  { userList: state }   // 這裏參數必須是個對象,並且對象裏面的鍵要和 combineReducers 設置的相同。
)
複製代碼

store 能夠接受三個參數,第一個參數是 reducer ,第二個參數表明狀態默認值,用於覆蓋 reducer 的默認狀態。dom

store 的第三個參數

目前的 store 並不具有處理異步 action 的能力,咱們可使用 中間件 來實現這個操做。異步

applyMiddlewarestore 的第三個參數,它是一個函數,用來拓展 store ,這個方法來源於 reduxide

  • logger
import { createLogger } from 'redux-logger';
  const logger = createLogger();
  
  const store = createStore( chatReducer, { userList: defaultUserList }, applyMiddleware(logger));
複製代碼

logger 能夠在發送 action 時打印狀態的變化以及 action 的信息:函數

  • redux-thunk
import thunk from 'redux-thunk';
  import { createLogger } from 'redux-logger';
  const logger = createLogger();
  const store = createStore(
    chatReducer,
    { userList: defaultUserList },
    applyMiddleware(thunk, logger)
  );
複製代碼

正常狀況下,dispatch 傳遞的參數只能是對象:

addUserData: (user) => {
  return dispatch({
    type: 'ADD_USER',
    payload: user
  })
}
複製代碼

使用 redux-thunkdispatch 接受一個函數,讓他可以進行異步操做:

addUserData: (user) => {
  return dispatch((dispatch, getState)=> {
    setTimeout(()=> {
      dispatch(addUser(user))
    }, 2000)
  })
}
複製代碼

傳遞一個函數以後,這個函數能夠接受兩個參數,一個是 dispatch ,另外一個是 getState ,而後在裏面進行異步操做,我這裏設置了 2秒 而後添加了一個用戶,點擊以後,過了 2秒 個人用戶纔會被添加進去,而頁面也是等到 2秒 後從新渲染。

這種異步思路就是使用 Action Creator 返回一個函數,而後使用 redux-thunkdispatch 可以接受一個函數做爲參數。

  • redux-promise
import thunk from 'redux-thunk';
  import { createLogger } from 'redux-logger';
  import promiseMiddleware from 'redux-promise';
  const logger = createLogger();
  const store = createStore(
    chatReducer,
    { userList: defaultUserList }, 
    applyMiddleware(thunk, promiseMiddleware, logger) // 按照嚴格的循序
  );
複製代碼

上一種方法是使用 Action Creator 返回函數來操做異步,使用 redux-promise 可讓它返回一個 promise 對象,可使用 then 來實現後面的操做。

deleteUserData: (index) => {
  return dispatch(new Promise((resolve, reject)=> {
    setTimeout(()=> {
      dispatch(deleteUser(index))
    }, 2000)
  }))
}
複製代碼

使用 redux-promise 讓它可以返回一個 使用 promise ,接着咱們調用 使用 deleteUserData 函數時就能夠執行 then 的操做。

總結

以上三個中間件都是對 store 的拓展,使用 applyMiddleware 而且分別傳入三個 中間件 ,傳入時必需要遵循順序,不然會出問題:

applyMiddleware(thunk, promiseMiddleware, logger)
複製代碼
相關文章
相關標籤/搜索