Lalas M
Lalas M

Reputation: 1174

How can I conditionally redirect to a page after the axios response in react?

How can I conditionally redirect to a page if the axios api is empty or a state is empty initially. In the following code I'm updating the state using axios and the user information is available in the state but the code keeps on calling to the http://userapi.com/login in loop. What I'm trying to achieve is, if the userinfo state is empty initially then redirect to the login page and authenticate.

class MyComponent extends React.Component {
  constructor() {
    super()
    this.state = {
      userinfo:{}
    }
  }
  
  componentDidMount(){
    axios.get('http://userapi.com/user')
    .then(res => {
        const userinfo = res.data;
        this.setState({ userinfo });
    })
    .catch(err => {
        console.log("Fetch error", err)
    })
    if (Object.keys(this.state.userinfo).length === 0) {
        window.location = 'http://userapi.com/login';
    }
  }
  render() {
    return (
      <React.Fragment>
        <Header>Welcome</Header>
      </React.Fragment>
    )
  }
}

I'm able to redirect fine but issue is with continuous loop. Even though the user information is storing the redirection is called (happens in loop)

Upvotes: 1

Views: 2419

Answers (4)

Heri Hehe Setiawan
Heri Hehe Setiawan

Reputation: 1633

You can try the following approach:

class HeaderComponent extends React.Component {
  constructor() {
    super()
    this.state = {
      userinfo:{}
    }
  }
  
  componentDidMount(){
    axios.get('http://userapi.com/user')
    .then(res => {
        const userinfo = res.data;
        this.setState({ userinfo });
    })
    .catch(err => {
        console.log("Fetch error", err)
    })
  }
  componentDidUpdate(prevProps, { userinfo }) {
    if (userinfo !== this.state.userinfo
        && Object.keys(this.state.userinfo.w3idUser || {}).length === 0) {
        window.location = 'http://userapi.com/login';
    }
  }
  render() {
    return (
      <React.Fragment>
        <Header>Welcome</Header>
      </React.Fragment>
    )
  }
}

The problem was that this.state.w3idUser never exists since you're mapping the response into userInfo state.

Upvotes: 2

Sahil Raj Thapa
Sahil Raj Thapa

Reputation: 2473

Axios returns Promise so the code with if condition below executes before the function that updates the state in then block. So if you need to check the updated state value after the request is successful, put your conditional inside then block.

componentDidMount() {
    axios
      .get('http://userapi.com/user')
      .then((res) => {
        const userinfo = res.data;
        this.setState({ userinfo }, () => {
          if (Object.keys(this.state.userinfo).length === 0) {
            window.location = 'http://userapi.com/login';
          }
        });
      })
      .catch((err) => {
        console.log('Fetch error', err);
      });
  }

Upvotes: 2

Besufkad Menji
Besufkad Menji

Reputation: 1588

i guess the issue is componentDidMount, you are redirecting before axios finish it's get request, refactor your code like below, you can show the sort of spinner until axios return value:

componentDidMount(){
axios.get('http://userapi.com/user')
.then(res => {
    const userinfo = res.data;
    this.setState({ userinfo });
   if (Object.keys(this.state.w3idUser).length === 0) {
    window.location = 'http://userapi.com/login';
}
})
.catch(err => {
    console.log("Fetch error", err)
})

}

it depends on the router you're using but if you want the javascript way check the code below:

// Simulate a mouse click:
window.location.href = "http://www.w3schools.com";

// Simulate an HTTP redirect:
window.location.replace("http://www.w3schools.com");

Upvotes: 0

Jason
Jason

Reputation: 367

Here when you are getting response...

.then(res => {
        const userinfo = res.data;
        this.setState({ userinfo });
    })

Check the res.data for user info. If you did receive a user then you can setState, if no user redirect to login page.

As far as redirecting look into react-router or react-router-dom

I wouldn't use pure javascript for redirecting/navigating in a React App.

Upvotes: 0

Related Questions