[英]Dispatch type usage in react redux
在 redux 動作中,當我們想要設置一個值時,我們使用一個類型來調度,如下所示:
dispatch({
type: SET_LOADER,
payload: true
})
其中type: SET_LOADER
存儲在不同的文件中並如下所示導出。
export const SET_LOADER = 'SET_LOADER'
在 reducer 中,我們將這樣做:
function initialState() {
return {
formErr: {},
isLoading: false
}
}
export default function (state = initialState(), action) {
const { type, payload } = action;
switch (type) {
case SET_LOADER:
return {
...state,
isLoading: payload
}
default:
return state
}
}
所以在我的應用程序中,我在不同的操作和減速器中使用了這個SET_LOADER
類型。 例如,在認證中,在配置文件更新中,當我要加載時,我會使用這種類型。 所以我在各個地方都進口了這種類型。
我不確定是否可以將單一類型用於多用途,因為我現在注意到,當我進行調度時,得到更新的 redux state 不屬於目標減速器。 state 更新發生在不同的減速器上。
但它是第一次調度。 下一次更新,它正在更新不正確的 redux state。 在我刷新頁面並嘗試再次更新后,它就可以工作了。
首先,您需要將減速器分成多個減速器,然后將它們組合在商店中,然后您可能可以通過在多種情況下使用相同的操作來逃脫,但它只是每個減速器的解決方案,這意味着讓我們說你有並且 Auth reducer 這個 reducer 將有它的isLoading
,它可能會干擾該 reducer 中的其他操作,例如FetchAllProducts
將使用isLoading
但FetchByIdProduct
正在使用isLoading
並且對於將觸發加載 state 的其他操作也是如此。
讓我們考慮這些使用相同初始 state 的減速器
function initialState() {
return {
formErr: {},
isLoading: false
}
}
export const authReducer=(state = initialState(), action)=> {
const { type, payload } = action;
switch (type) {
case SET_LOADER:
return {
...state,
isLoading: payload
}
default:
return state
}
}
export const productsReducer=(state = initialState(), action)=> {
const { type, payload } = action;
switch (type) {
case SET_LOADER:
return {
...state,
isLoading: payload
}
default:
return state
}
}
export const cartReducer =(state = initialState(), action)=> {
const { type, payload } = action;
switch (type) {
case SET_LOADER:
return {
...state,
isLoading: payload
}
default:
return state
}
}
//this is the store
import {createStore,applyMiddleware,compose,combineReducers} from 'redux'
import thunk from 'redux-thunk'
import {productsReducer} from './reducers/ProductReducer'
import {cartReducer} from './reducers/CartReducer'
import {authReducer } from './reducers/AuthReducer'
const initialState={
products: {
formErr: {},
isLoading: false
},
cart: {
formErr: {},
isLoading: false
},
auth: {
formErr: {},
isLoading: false
}
}
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(combineReducers({
products: productsReducer,
cart : cartReducer ,
auth : authReducer,
}),
initialState,
composeEnhancer(applyMiddleware(thunk))
)
export default store
即使他們使用相同的初始 state 您,當您將組件連接到 redux 商店時,您可以訪問三個不同isLoading
:
export default connect((state)=>({
isLoading : state.products.isLoading,
isLoading2: state.authReducer.isLoading,
isLoading3: state.cart.isLoading,
}))(Products)
但老實說,我寧願讓我的操作更加明確和具體案例,比如productsFetchIsLoading
,這樣可以讓你有更多的控制權並防止錯誤
我現在注意到,當我進行調度時,更新的 redux state 不屬於目標減速器。 state 更新發生在不同的減速器上。
每個動作都被分派給每個減速器。 當您調用dispatch({ type: SET_LOADER, payload: true })
時,預期的行為是isLoading
state 將在每個具有case SET_LOADER
的減速器中設置為true
。
如果您希望加載狀態是獨立的,那么每個 reducer 都需要一個唯一的string
操作類型。
如果您有多個類似的減速器,那么您可以使用工廠 function 來生成類型名稱、動作創建函數和減速器案例。 在這里,我們從 Redux Toolkit 擴展createSlice
實用程序。
我們傳入作為自動生成動作類型前綴的name
、僅此減速器initialState
的唯一屬性的初始狀態以及任何唯一減速器案例。 這將與標准基礎 state 合並。
幫手:
const createCustomSlice = ({name, initialState = {}, reducers = {}}) => {
return createSlice({
name,
initialState: {
formErr: {},
isLoading: false
...initialState,
},
reducers: {
setLoader: (state, action) => {
state.isLoading = action.payload;
},
setFormErr: (state, action) => {
state.formErr = action.payload;
}
...reducers,
}
});
}
用法:
const profileSlice = createCustomSlice({
name: "profile",
initialState: {
username: ""
},
reducers: {
setUsername: (state, action) => {
state.username = action.payload;
}
}
});
// reducer function
const profileReducer = profileSlice.reducer;
// action creator functions
export const { setFormErr, setLoader, setUsername } = profileSlice.actions;
這些動作創建者將創建帶有前綴type
的動作,例如'profile/setLoader'
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.