Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React and Redux: redirect after action

I develop a website with React/Redux and I use a thunk middleware to call my API. My problem concerns redirections after actions.

I really do not know how and where I can do the redirection: in my action, in the reducer, in my component, … ?

My action looks like this:

export function deleteItem(id) {
    return {
        [CALL_API]: {
            endpoint: `item/${id}`,
            method: 'DELETE',
            types: [DELETE_ITEM_REQUEST, DELETE_ITEM_SUCCESS, DELETE_ITEM_FAILURE]
        },
        id
    };
}

react-redux is already implemented on my website and I know that I can do as below, but I do not want to redirect the use if the request failed:

router.push('/items');

Thanks!

like image 897
vermotr Avatar asked Mar 23 '17 19:03

vermotr


People also ask

How do you redirect after form submit react?

To redirect on form submit using React Router: Use the useNavigate() hook, e.g. const navigate = useNavigate(); . Call the navigate() function passing it the path - navigate('/contacts') . The navigate() function lets us navigate programmatically.

How do I redirect after Axios Post react?

To make redirects after an axios post request with Express and React, we set window. location to the new URL value after the response from the axios request to the Express back end is available. import React, { Component } from "react"; //... class MyClass extends Component { onSubmit = async (e) => { e.

How do I redirect to another page in react?

To redirect to another page on button click in React: Use the useNavigate() hook, e.g. const navigate = useNavigate(); . Call the navigate() function, passing it the path - navigate('/about') . The navigate() function lets us navigate programmatically.


3 Answers

Definitely do not redirect from your reducers since they should be side effect free. It looks like you're using api-redux-middleware, which I believe does not have a success/failure/completion callback, which I think would be a pretty useful feature for the library.

In this question from the middleware's repo, the repo owner suggests something like this:

// Assuming you are using react-router version < 4.0
import { browserHistory } from 'react-router';

export function deleteItem(id) {
  return {
    [CALL_API]: {
      endpoint: `item/${id}`,
      method: 'DELETE',
      types: [
        DELETE_ITEM_REQUEST, 
        {
          type: DELETE_ITEM_SUCCESS,
          payload: (action, state, res) => {
            return res.json().then(json => {
              browserHistory.push('/your-route');
              return json;
            });
          },
        },
        DELETE_ITEM_FAILURE
      ]
    },
    id
  }
};

I personally prefer to have a flag in my connected component's props that if true, would route to the page that I want. I would set up the componentWillReceiveProps like so:

componentWillReceiveProps(nextProps) {
  if (nextProps.foo.isDeleted) {
    this.props.router.push('/your-route');
  }
}
like image 91
Yo Wakita Avatar answered Sep 29 '22 08:09

Yo Wakita


The simplest solution

You can use react-router-dom version *5+ it is actually built on top of react-router core.

Usage:

You need to import useHistory hook from react-router-dom and directly pass it in your actions creator function call.

Import and Creating object

import { useHistory } from "react-router-dom";

const history = useHistory();

Action Call in Component:

dispatch(actionName(data, history));

Action Creator Now, you can access history object as a function argument in action creator.

function actionName(data, history) {}
like image 22
Muhammad Usman Avatar answered Sep 29 '22 08:09

Muhammad Usman


Usually the better practice is to redirect in the component like this:

render(){
   if(requestFullfilled){
       router.push('/item')
   }
   else{
       return(
          <MyComponent />
       )
   }
}
like image 25
Prakash Sharma Avatar answered Sep 29 '22 09:09

Prakash Sharma