Home > front end >  How to call navigate inside Redux Toolkit's actions in React js
How to call navigate inside Redux Toolkit's actions in React js

Time:03-23

I've a simple app built on redux-toolkit. I am dispatching createProduct actions which is working fine. I want to navigate to /products/ page form /products/new page after createProduct action. How can I use navigate (react-router-dom) to do this.

I tried this inside action but failes

 [createProduct.fulfilled]: (state, { payload }) => {
      toast.success('Product Created Successfully!');
      const navigate = useNavigate()
      navigate('/products')
      return {
        ...state,
        loading: false,
        products: state.products ? [...state.products, payload.product] : [payload.product]
      };
    },

I also tried passing navigate to payload but I encountered this error :

 You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.

I am dispatching createProduct like this

 const handleSubmit = async () => {
    console.log('formik.values', formik.values);
    dispatch(
      createProduct({
        ...formik.values,
        category: formik.values.category._id,
        subCategory: formik.values.subCategory._id
      })
    )
  };

CodePudding user response:

The result of dispatching a thunk action is a Promise. Redux toolkit wraps this Promise so that there are no uncaught errors in your component. It always resolves to either a success or failure action. But you can unwrap() the result to use it with a try/catch.

const dispatch = useDispatch();

const navigation = useNavigation();

const handleSubmit = async (e) => {
  try {
    // wait for the action to complete successfully
    const response = await dispatch(...).unwrap();
    // then navigate
    navigate(...);
  } catch (error) {
    // do something
  }
}

CodePudding user response:

Reducer functions are pure functions, you can't issue the navigation action from the reducer, but you can from the asynchronous action or in the calling component. React hooks are also only valid in React functions or custom hooks.

Asynchronous actions return a Promise. You can chain from the resolved Promise, or await it, and issue the imperative navigation.

const navigate = useNavigate();

Using Promise chain:

const handleSubmit = () => {
  dispatch(createProduct({
    ...formik.values,
    category: formik.values.category._id,
    subCategory: formik.values.subCategory._id
  }))
    .then(() => {
      navigate('/products');
    });
};

or async/await:

const handleSubmit = async () => {
  try {
    await dispatch(createProduct({
      ...formik.values,
      category: formik.values.category._id,
      subCategory: formik.values.subCategory._id
    }));
    navigate('/products');
  } catch(error) {
    // handle any rejections/errors
  }
};
  • Related