[英]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.