Redux中進行異步操作(網絡請求)的示例方案
Redux中的異步操作
在之前簡單的案例中,redux中保存的counter是一個本地定義的數據
我們可以直接通過同步的操作來dispatch action,state就會被立即更新。
但是真實開發(fā)中,redux中保存的很多數據可能來自服務器,我們需要進行異步的請求,再將數據保存到redux中。
在之前學習網絡請求的時候我們講過,發(fā)生網絡請求我們有兩種方案, 可以直接在組件的鉤子函數中發(fā)送網絡請求, 再將數據存放到store中; 也可以直接在store中發(fā)生網絡請求
組件中進行異步操作
網絡請求可以在class組件的生命周期函數componentDidMount中發(fā)送,所以我們可以有這樣的結構:

我現在完成如下案例操作:
創(chuàng)建一個組件Category, 在該組件中發(fā)送網絡請求, 獲取banners和recommends的數據;
在About組件中展示banners和recommends的數據;
首先需要創(chuàng)建要派發(fā)的action, 以及對應的reducer
// store/actionCreators.jsx
import { CHANGE_BANNERS, CHANGE_RECOMMENDS } from "./constants"
export const changeBannersAction = (banners) => ({
type: CHANGE_BANNERS,
banners
})
export const changeRecommendsAction = (recommends) => ({
type: CHANGE_RECOMMENDS,
recommends
})// store/reducer.jsx
import { CHANGE_BANNERS, CHANGE_RECOMMENDS } from "./constants"
const initialState = {
banners: [],
recommends: []
}
export default function reducer(state = initialState, action) {
switch(action.type) {
case CHANGE_BANNERS:
return {...state, [banners: action.banners}
case CHANGE_RECOMMENDS:
return {...state, recommends: action.recommends}
default:
return state
}
}在Categroy組件中發(fā)送網絡請求, 并將store中的banners和recommends修改為網絡請求后的數據
import React, { PureComponent } from 'react'
import axios from 'axios'
import { connect } from 'react-redux'
import { changeBannersAction, changeRecommendsAction } from '../store/actionCreators'
export class Category extends PureComponent {
componentDidMount() {
// 發(fā)送網絡請求, 獲取到banners和recommends數據
axios.get("http://123.207.32.32:8000/home/multidata").then(res => {
const banners = res.data.data.banner.list
const recommends = res.data.data.recommend.list
console.log(banners, recommends)
// 調用映射過來的方法, 修改banners和recommends
this.props.changeBanners(banners)
this.props.changeRecommends(recommends)
})
}
render() {
return (
<div>Category</div>
)
}
}
// 映射方法用于修改store中的banners和recommends
const mapDispatchToProps = (dispatch) => ({
changeBanners(banners) {
dispatch(changeBannersAction(banners))
},
changeRecommends(recommends) {
dispatch(changeRecommendsAction(recommends))
}
})
export default connect(null, mapDispatchToProps)(Category)
目前, store中存放的就是網絡請求獲取到的數據, 接下來就在About頁面進行展示
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
export class About extends PureComponent {
render() {
// 在props中獲取到映射過來的數據
const { banners, recommends } = this.props
return (
<div>
<h2>輪播圖展示</h2>
<ul>
{
banners.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
<h2>推薦數據展示</h2>
<ul>
{
recommends.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
</div>
)
}
}
const mapStateToProps = (state) => ({
banners: state.banners,
recommends: state.recommends
})
// 表示將數據映射到About組件中
export default connect(mapStateToProps)(About)redux中進行異步操作
上面的代碼有一個缺陷:
我們必須將網絡請求的異步代碼放到組件的生命周期中來完成;
事實上,網絡請求到的數據也屬于我們狀態(tài)管理的一部分,更好的一種方式應該是將其也交給redux來管理;

但是在redux中如何可以進行異步的操作呢?
答案就是使用中間件(Middleware), 如果學習過Express或Koa框架的小伙伴對中間件的概念一定不陌生;
由于在正常情況下,
store.dispatch()只能派發(fā)一個對象, 不能派發(fā)函數; 如果dispatch想要派發(fā)函數, 我們必須要使用中間件對該store進行增強
使用中間件, 在redux中發(fā)送網絡請求
首先安裝redux-thunk庫, 引入中間件
安裝redux-thunk庫:
npm i redux-thunk, 在該庫中有一個中間件thunk, 如下方式應用thunk中間件
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
// 導入中間件
import thunk from "redux-thunk";
// 應用中間件
const store = createStore(reducer, applyMiddleware(thunk))
export default store應用之后,
store.dispatch()就可以派發(fā)函數了
// 定義一個返回函數的action
export const fetchHomeMultidataAction = () => {
function foo() {
console.log("aaa")
}
return foo
}// 派發(fā)action
const mapDispatchToProps = (dispatch) => ({
fetchHomeMultidata() {
// 派發(fā)一個函數, 內部返回的函數自動執(zhí)行
dispatch(fetchHomeMultidataAction())
}
})自動執(zhí)行action中的返回的函數時, 會傳給這個函數一個dispatch函數和getState函數;
dispatch函數: 用于我們之后再次派發(fā)action;
getState函數: 考慮到我們之后的一些操作需要依賴原來的狀態(tài),調用getState函數可以讓我們可以獲取之前的一些狀態(tài);我們就可以在返回的該函數中, 編寫異步的網絡請求相關代碼
import axios from "axios"
export const changeBannersAction = (banners) => ({
type: CHANGE_BANNERS,
banners
})
export const changeRecommendsAction = (recommends) => ({
type: CHANGE_RECOMMENDS,
recommends
})
export const fetchHomeMultidataAction = () => {
// 派發(fā)時返回的該函數自動執(zhí)行, 且傳入兩個參數dispatch, getState
return (dispatch, getState) => {
axios.get("http://123.207.32.32:8000/home/multidata").then(res => {
const banners = res.data.data.banner.list
const recommends = res.data.data.recommend.list
// 獲取到數據后在派發(fā)action
dispatch(changeBannersAction(banners))
dispatch(changeRecommendsAction(recommends))
})
}
}
到此這篇關于Redux中進行異步操作(網絡請求)的方案的文章就介紹到這了,更多相關Redux異步操作內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JS.getTextContent(element,preformatted)使用介紹
JS.getTextContent獲取標簽的文字想必大家并不陌生吧,下面為大家介紹下具體的使用方法,感興趣的朋友可以參考下2013-09-09
用javascript實現點擊鏈接彈出"圖片另存為"而不是直接打開
用javascript實現點擊鏈接彈出"圖片另存為"而不是直接打開...2007-08-08
詳解微信小程序scroll-view橫向滾動的實踐踩坑及隱藏其滾動條的實現
這篇文章主要介紹了詳解微信小程序scroll-view橫向滾動的實踐踩坑及隱藏其滾動條的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03

