簡體   English   中英

反應 redux 中的調度類型用法

[英]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將使用isLoadingFetchByIdProduct正在使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM