简体   繁体   中英

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)

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);
      });
  }

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.

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");

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM