14.4 react-redux第三方庫
提供connect、thunk之類的函數
以獲取一個banner數據為例子
store:
我們在使用異步的時候理應是要使用中間件的,但是configureStore 已經自動集成了 redux-thunk,注意action里面要返回函數
import { configureStore } from '@reduxjs/toolkit';//Redux Toolkit 推薦的創建 store 的方法,自動集成了開發工具和中間件。
import rootReducer from './reducer/reducer.js'//項目中所有 reducer 的集合
//configureStore 已經自動集成了 redux-thunk
const store = configureStore({ reducer: rootReducer });
export default store;
action:
import { CHANGE_BANNERS } from './constant.js' // 導入 action 類型常量
import axios from 'axios' // 導入 axios 用于發起 HTTP 請求// 普通 action creator,返回一個 action 對象
export const changeBannersAction = (data) => ({type: CHANGE_BANNERS, // action 類型payload: data // 傳遞的數據
});
**reducer:**我們是先寫了一個總的reducer,合并多個 reducer,生成根 reducer 并導出,用于 Redux 的全局狀態管理。
import { combineReducers } from 'redux';
import bannerReducer from './bannerReducer';const rootReducer = combineReducers({banner : bannerReducer
});export default rootReducer;
分reducer:bannerReducer:
import { CHANGE_BANNERS } from "../constant"
// 初始化狀態
const initailState = {banner : []
}
// 據不同的 action 類型決定如何更新 state。
const bannerReducer = (state = initailState , action) => {switch(action.type){default:return state;}}export default bannerReducer;
constant:
定義一些常量
引入store:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from './store';
// 引用provider將store進行傳遞
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Provider store={store}><App /></Provider>
);
為什么要使用中間件???因為reducer必須是純函數,這意味著它不能直接處理異步操作,異步操作必須在action之后的中間件處理之后生成原始的action,這樣,reducer函數就能處理相應的action,從而改變state,更新UI。
thunk有什么缺點:
- Redux Thunk 在處理異步操作時,通常需要編寫大量的樣板代碼。
- Redux Thunk 將異步邏輯與 Redux 的 action 緊密耦合在一起。這意味著 action creator 不僅需要定義 action 類型,還需要處理異步邏輯。
saga:
引入:創建中間件,應用中間件,run中間件
import { configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import mySaga from './saga';
import rootReducer from './reducer';
// 創建saga中間件
const sagaMiddleware = createSagaMiddleware();
// 定義store:reducer+中間件
const store = configureStore({reducer: rootReducer,middleware: (getDefaultMiddleware) =>getDefaultMiddleware().concat(sagaMiddleware)
});
// 使用中間件
sagaMiddleware.run(mySaga);export default store;
saga.js中監聽actionTyp然后執行邏輯代碼
import {put, takeEvery} from 'redux-saga/effects'
import axios from 'axios'
import { FETCH_HOME_MULTIDATA } from './constant';
import { changeBannersAction } from './actionCreator';
// 定義異步函數:*
function* fetchHomeMultidata(){const res = yield axios.get('http://123.207.32.32:8000/home/multidata')const banner = res.data.data.banner.list;
// 發送yield put(changeBannersAction(banner))
}
// 監聽
function* mySaga(){yield takeEvery( FETCH_HOME_MULTIDATA, fetchHomeMultidata )
}export default mySaga;
redux-thunk
const store = configureStore({ reducer: rootReducer });
export default store;
**action**:
import { CHANGE_BANNERS } from ‘./constant.js’ // 導入 action 類型常量
import axios from ‘axios’ // 導入 axios 用于發起 HTTP 請求
// 普通 action creator,返回一個 action 對象
export const changeBannersAction = (data) => ({
type: CHANGE_BANNERS, // action 類型
payload: data // 傳遞的數據
});
**reducer:**我們是先寫了一個總的reducer,合并多個 reducer,生成根 reducer 并導出,用于 Redux 的全局狀態管理。
import { combineReducers } from ‘redux’;
import bannerReducer from ‘./bannerReducer’;
const rootReducer = combineReducers({
banner : bannerReducer
});
export default rootReducer;
分reducer:**bannerReducer**:
import { CHANGE_BANNERS } from “…/constant”
// 初始化狀態
const initailState = {
banner : []
}
// 據不同的 action 類型決定如何更新 state。
const bannerReducer = (state = initailState , action) => {
switch(action.type){
default:
return state;
}
}
export default bannerReducer;
constant:定義一些常量**引入store:**
import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import App from ‘./App’;
import store from ‘./store’;
// 引用provider將store進行傳遞
import { Provider } from ‘react-redux’;
const root = ReactDOM.createRoot(document.getElementById(‘root’));
root.render(
);
為什么要使用中間件???因為reducer必須是純函數,這意味著它不能直接處理異步操作,異步操作必須在action之后的中間件處理之后**生成原始的action,這樣,reducer函數就能處理相應的action,從而改變state,更新UI。**thunk有什么缺點:- Redux Thunk 在處理異步操作時,通常需要編寫大量的樣板代碼。
- Redux Thunk 將異步邏輯與 Redux 的 action 緊密耦合在一起。這意味著 action creator 不僅需要定義 action 類型,還需要處理異步邏輯。saga:引入:創建中間件,應用中間件,run中間件
import { configureStore } from ‘@reduxjs/toolkit’;
import createSagaMiddleware from ‘redux-saga’;
import mySaga from ‘./saga’;
import rootReducer from ‘./reducer’;
// 創建saga中間件
const sagaMiddleware = createSagaMiddleware();
// 定義store:reducer+中間件
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(sagaMiddleware)
});
// 使用中間件
sagaMiddleware.run(mySaga);
export default store;
saga.js中監聽actionTyp然后執行邏輯代碼
import {put, takeEvery} from ‘redux-saga/effects’
import axios from ‘axios’
import { FETCH_HOME_MULTIDATA } from ‘./constant’;
import { changeBannersAction } from ‘./actionCreator’;
// 定義異步函數:*
function* fetchHomeMultidata(){
const res = yield axios.get(‘http://123.207.32.32:8000/home/multidata’)
const banner = res.data.data.banner.list;
// 發送
yield put(changeBannersAction(banner))
}
// 監聽
function* mySaga(){
yield takeEvery( FETCH_HOME_MULTIDATA, fetchHomeMultidata )
}
export default mySaga;