Reputation: 1174
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
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
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
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
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