Home > Mobile >  Redux toolkit update state in thunk
Redux toolkit update state in thunk

Time:10-03

I have an initial state like this.

const initialState = {
    loading: false,
    products: []
}

For the get products, I use thunk and I fetch datas from an API. loading field describes status of API call. If loading is true, i show progress in my component.

export const getProducts = createAsyncThunk('product/getProducts ',
    async (payload, { rejectWithValue }) => {
        try {
            //fetch from somewhere
        }
        catch (e) {
            return rejectWithValue(e.message)
        }
    }
)

const productSlice = createSlice({
    name: "product",
    initialState,
    reducers: {
        setLoading: (state, action) => {
            state.loading = action.payload;
        }
    },
})

In a component first dispatch for loading and then getProducts.

// In some component
  dispatch(setLoading(true))
  dispatch(getProducts())

My question is, can I only call for getProducts and update loading state inside that function?

//In some component
 dispatch(getProducts())

CodePudding user response:

Yes you can. This is very simple

Update your createSlice section like this

const productSlice = createSlice({
    name: "product",
    initialState,
    reducers: {},
    extraReducers: (builder) => {
      builder.addCase(getProducts.pending, (state) => {
        state.loading = true;
      });

      builder.addCase(getProducts.fulfilled, (state) => {
        state.loading = false;
      });
    },
}) 

CodePudding user response:

You used createAsyncThunk and it is built in already to handle pending/fulfilled/rejected state with extraReducers in createSlice. You can also handle the rejected state if fetch fail.

const productSlice = createSlice({
  name: 'product',
  initialState,
  extraReducers: (builder) => {
    builder.addCase(getProducts.pending, (state, action) => {
      state.isLoading = true;
    })
    builder.addCase(getProducts.fulfilled, (state, action) => {
      state.isLoading = true;
      state.products = action.payload
    })
    builder.addCase(getProducts.rejected, (state, action) => {
      state.isLoading = false;
    })
  },
})

To use it, will be enough to simple call dispatch(getProducts()) and extraReducers with thunk take care of the rest.

  • Related