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

我現(xiàn)在完成如下案例操作:
創(chuàng)建一個(gè)組件Category, 在該組件中發(fā)送網(wǎng)絡(luò)請(qǐng)求, 獲取banners和recommends的數(shù)據(jù);
在About組件中展示banners和recommends的數(shù)據(jù);
首先需要?jiǎng)?chuàng)建要派發(fā)的action, 以及對(duì)應(yīng)的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ā)送網(wǎng)絡(luò)請(qǐng)求, 并將store中的banners和recommends修改為網(wǎng)絡(luò)請(qǐng)求后的數(shù)據(jù)
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ā)送網(wǎng)絡(luò)請(qǐng)求, 獲取到banners和recommends數(shù)據(jù)
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)
// 調(diào)用映射過來的方法, 修改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中存放的就是網(wǎng)絡(luò)請(qǐng)求獲取到的數(shù)據(jù), 接下來就在About頁(yè)面進(jìn)行展示
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
export class About extends PureComponent {
render() {
// 在props中獲取到映射過來的數(shù)據(jù)
const { banners, recommends } = this.props
return (
<div>
<h2>輪播圖展示</h2>
<ul>
{
banners.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
<h2>推薦數(shù)據(jù)展示</h2>
<ul>
{
recommends.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
</div>
)
}
}
const mapStateToProps = (state) => ({
banners: state.banners,
recommends: state.recommends
})
// 表示將數(shù)據(jù)映射到About組件中
export default connect(mapStateToProps)(About)redux中進(jìn)行異步操作
上面的代碼有一個(gè)缺陷:
我們必須將網(wǎng)絡(luò)請(qǐng)求的異步代碼放到組件的生命周期中來完成;
事實(shí)上,網(wǎng)絡(luò)請(qǐng)求到的數(shù)據(jù)也屬于我們狀態(tài)管理的一部分,更好的一種方式應(yīng)該是將其也交給redux來管理;

但是在redux中如何可以進(jìn)行異步的操作呢?
答案就是使用中間件(Middleware), 如果學(xué)習(xí)過Express或Koa框架的小伙伴對(duì)中間件的概念一定不陌生;
由于在正常情況下,
store.dispatch()只能派發(fā)一個(gè)對(duì)象, 不能派發(fā)函數(shù); 如果dispatch想要派發(fā)函數(shù), 我們必須要使用中間件對(duì)該store進(jìn)行增強(qiáng)
使用中間件, 在redux中發(fā)送網(wǎng)絡(luò)請(qǐng)求
首先安裝redux-thunk庫(kù), 引入中間件
安裝redux-thunk庫(kù):
npm i redux-thunk, 在該庫(kù)中有一個(gè)中間件thunk, 如下方式應(yīng)用thunk中間件
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
// 導(dǎo)入中間件
import thunk from "redux-thunk";
// 應(yīng)用中間件
const store = createStore(reducer, applyMiddleware(thunk))
export default store應(yīng)用之后,
store.dispatch()就可以派發(fā)函數(shù)了
// 定義一個(gè)返回函數(shù)的action
export const fetchHomeMultidataAction = () => {
function foo() {
console.log("aaa")
}
return foo
}// 派發(fā)action
const mapDispatchToProps = (dispatch) => ({
fetchHomeMultidata() {
// 派發(fā)一個(gè)函數(shù), 內(nèi)部返回的函數(shù)自動(dòng)執(zhí)行
dispatch(fetchHomeMultidataAction())
}
})自動(dòng)執(zhí)行action中的返回的函數(shù)時(shí), 會(huì)傳給這個(gè)函數(shù)一個(gè)dispatch函數(shù)和getState函數(shù);
dispatch函數(shù): 用于我們之后再次派發(fā)action;
getState函數(shù): 考慮到我們之后的一些操作需要依賴原來的狀態(tài),調(diào)用getState函數(shù)可以讓我們可以獲取之前的一些狀態(tài);我們就可以在返回的該函數(shù)中, 編寫異步的網(wǎng)絡(luò)請(qǐng)求相關(guān)代碼
import axios from "axios"
export const changeBannersAction = (banners) => ({
type: CHANGE_BANNERS,
banners
})
export const changeRecommendsAction = (recommends) => ({
type: CHANGE_RECOMMENDS,
recommends
})
export const fetchHomeMultidataAction = () => {
// 派發(fā)時(shí)返回的該函數(shù)自動(dòng)執(zhí)行, 且傳入兩個(gè)參數(shù)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
// 獲取到數(shù)據(jù)后在派發(fā)action
dispatch(changeBannersAction(banners))
dispatch(changeRecommendsAction(recommends))
})
}
}
到此這篇關(guān)于Redux中進(jìn)行異步操作(網(wǎng)絡(luò)請(qǐng)求)的方案的文章就介紹到這了,更多相關(guān)Redux異步操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS.getTextContent(element,preformatted)使用介紹
JS.getTextContent獲取標(biāo)簽的文字想必大家并不陌生吧,下面為大家介紹下具體的使用方法,感興趣的朋友可以參考下2013-09-09
用javascript實(shí)現(xiàn)點(diǎn)擊鏈接彈出"圖片另存為"而不是直接打開
用javascript實(shí)現(xiàn)點(diǎn)擊鏈接彈出"圖片另存為"而不是直接打開...2007-08-08
簡(jiǎn)單實(shí)現(xiàn)節(jié)流函數(shù)和防抖函數(shù)過程解析
這篇文章主要介紹了簡(jiǎn)單實(shí)現(xiàn)節(jié)流函數(shù)和防抖函數(shù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
JS實(shí)現(xiàn)文檔加載完成后執(zhí)行代碼
本文給大家講述的是使用javascript實(shí)現(xiàn)文檔加載完成后再執(zhí)行代碼的方法和示例,非常簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。2015-07-07
淺析Virtual DOM的概念與其在現(xiàn)代前端框架中的實(shí)踐
這篇文章將深入探討Virtual DOM(虛擬DOM)的概念,分析其對(duì)前端開發(fā)的革新影響,并以此展示前端技術(shù)的深度和魅力,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12
詳解微信小程序scroll-view橫向滾動(dòng)的實(shí)踐踩坑及隱藏其滾動(dòng)條的實(shí)現(xiàn)
這篇文章主要介紹了詳解微信小程序scroll-view橫向滾動(dòng)的實(shí)踐踩坑及隱藏其滾動(dòng)條的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03

