react的異步action跨域獲取數據(中間件thunk以及redux-promise-middleware的使用)

react中跨域獲取數據的過程

首先進行跨域的設置
在項目src目錄下添加一個setupProxy.js的文件

const proxy = require("http-proxy-middleware");

module.exports = (app) => {
    app.use("/api", proxy({//api是隨便寫的
        target: "",//這裏寫要代理的地址必須寫
        changeOrigin: true,
        pathRewrite: {
            "^/api": ""//將路徑中的api替換掉
        }
    }))
}

這樣跨域就可以了

接下來就是創建倉庫保存數據了,這裏用到了redux、redux-immutable、immutable以及redux-thunk
在src文件夾下創建store文件夾(類似於vue),在store目錄下創建index.js
在這個裏面使用redux的createStore()方法創建store倉庫,裏面的參數需要reducers,在這裏我們是根據reducers中的state的只讀的特點使用了immutable來創建的,他可以保證數據的只讀性,如果想要了解immutable中數據的特點可以去看一下他的官網。

Reducers 指定了應用狀態的變化如何響應 actions 併發送到 store 的,記住 actions 只是描述了有事情發生了這一事實,並沒有描述應用如何更新 state。
處理 Reducer 關係時的注意事項
開發複雜的應用時,不可避免會有一些數據相互引用。建議你儘可能地把 state 範式化,不存在嵌套。把所有數據放到一個對象裏,每個數據以 ID 爲主鍵,不同實體或列表間通過 ID 相互引用數據。把應用的 state 想像成數據庫。
上代碼

import {
    createStore,
    applyMiddleware
} from "redux"; //引入創建倉庫和使用中間件的方法
import {combineReducers} from "redux-immutable"//引入合併
import reducersa from "./reducers/a"  
  //引入reducersa.js
import reducersb from "./reducers/b" 
   //引入reducersa.js
import thunk from "redux-thunk"		
//引入thunk中間件處理異步action
import reduxPromiseMiddleware from "redux-promise-middleware"
 //引入redux-promise-middleware中間件處理異步action
//需要注意,以上兩個中間件的action的要求不同,在下面以會詳細介紹

const reducers = combineReducers({reducersa ,reducersb});
//將兩個reducers合併

const store = createStore(reducers, applyMiddleware(reduxPromiseMiddleware));
//創建倉庫並使用reducers以及使用中間件
export default store;

reducersa.j
reducersb.js與reducersa的結構一樣只是裏面的數據不同

import Immutable from "immutable"
//引入immutable對

const defaultState = Immutable.fromJS({
        val:"111"
})

export default (state=defaultState,action)=>{
  //要導出一個純函數(輸入一定,輸出也一定)
    switch(action.type){
      // 根據action.type進行數據的操作,返回操作後的新的newState;
    }
    return state;
}

然後就到了頁面進行操作的時候了
創建一個頁面
在這裏使用到了react-redux中的兩大組件Provider 以及connect

App.js

import React, { Component } from 'react';
import {Provider} from "react-redux"
//引入provider 屬性store會將數據添加到每一個組件中,在組件中通過connect函數獲取數據
 import Com_Afrom "./components/Com_A"

import store from "./store"
//引入store

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <div>
        <Com_A/>
        </div>
     </Provider>
    )
  }
}

export default App;

Com_A.js組件

import React from "react"
import {connect} from "react-redux"
//在組件中引入connect來接受app.js傳遞的store

import { getData,getData2} from "../store/action/actionCreator"
引入getData以及getData2(這是兩個action函數)

class ComA extends React.Component{

    render() {
        let { val} = this.props;
        return (
      			<div>
      				{val}
      			</div>
        )
    }
    componentDidMount() {
        this.props.handleData();
        //調用方法獲取數據
    }


}
const mapStateToProps= (state)=>({
        val.getIn(["reducersa","val"])
})
const  mapDispatchToProps=(dispatch)=>({
    handleData() {
        // dispatch(getData());
			第一種方式使用的是redux-thunk直接調用getData(),使用thunk時他會檢測到dispatch裏面的參數是一個函數然後會在getData函數裏面的到兩個參數dispatch和getState在裏面可以進行派發action,詳細看一下actionCreator代碼。
			
        getData2(dispatch);
     //   第二種方式使用的是redux-promise-middleware 將dispatch方法傳過去,然後在函數裏面派發action,詳細看一下actionCreator代碼。
        }
})
export default connect(mapStateToProps,mapDispatchToProps)(ComA);

ActionCreator.js

import { fetch } from 'whatwg-fetch';

export const getData = () => {
    let action = (data) => ({
        type: "GET_DATA",
        val: data
    });
    //action函數用來創建action
    return (dispatch, getState) => {
        let url = "";
        fetch(url).then((res)=>{
            return res.json();
        }).then((result)=>{
            dispatch(action(result));//派發action
        })
    }
}
export const getData2 =(dispatch)=>{
    dispatch({
    //裏面的參數固定,必須是tyoe以及payload而且payload的值是一個promise對象
        type:"GET_DATA",
        payload:new Promise(resolve=>{
                        let url = "";
                        fetch(url).then((res)=>{
                            return res.json();
                        }).then((result)=>{
                            // console.log(result);
                           resolve( result)
                        })
        })
    })
}

最後在reducers裏面就可以對數據進行修改了
記得數據類型是immutable類型的
還有一個方法是投機取巧就是在componentDIdMount生命週期裏面進行數據的請求然後請求到數據後進行action的派發,over

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章