I have this privateRoute component that I use to manage authentication:
const PrivateRoute = ({ component: Component, auth, ...rest }) => {
// This gets logged twice when I navigate in the app
// Using history.push("/url")
// And gets logged once when I type the url and hit enter on the browser
console.log(
"===============INSIDE PrivateRoute Component========================"
);
return (
<Route
{...rest}
render={(props) =>
auth.isAuthenticated === true ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
};
The strange thing is that this component gets logged twice when I navigate in the app. For example, when I hit a button that triggers this code:
this.props.history.push("/edit-page-after-login");
And I have this in App.js:
<PrivateRoute
path="/edit-page-after-login"
component={EditProfileAfterLogin}
/>
And I have a component that gets rendered in that route:
export default class EditProfileInSettings extends Component {
componentDidMount() {
console.log(
" ~ file: EditProfileInSettings.js ~ line 5 ~ EditProfileInSettings ~ componentDidMount ~ componentDidMount"
);
}
render() {
return <div>Test</div>;
}
}
So when I navigate to that component using history.push, this gets logged:
===============INSIDE PrivateRoute Component========================
~ file: EditProfileInSettings.js ~ line 5 ~ EditProfileInSettings ~ componentDidMount ~ componentDidMount
===============INSIDE PrivateRoute Component========================
For some strange reason, PrivateRoute component gets called TWICE which is causing me some issues in the logic I am trying to implement.
But, when I write the url in the browser and enter, it behaves correctly and it only gets called ONCE:
===============INSIDE PrivateRoute Component========================
~ file: EditProfileInSettings.js ~ line 5 ~ EditProfileInSettings ~ componentDidMount ~ componentDidMount
Any idea what's going on here?
EDIT 1: I have noticed this error only occurs when I do an API call to the backend inside the component:
class PrivateRouteTestComponent extends Component {
componentDidMount() {
console.log("PrivateRouteTestComponent.componentDidMount is called!");
// If I comment this out, the problem will not occur.
// It only occurs with this line
// It does an API call to the backend to get user profile
this.props.getAuthenticatedUserProfile();
}
render() {
return (
<div>
<button
onClick={() => {
this.props.history.push("/videos-page");
}}
>
Home
</button>
<h6>Private route test component</h6>
</div>
);
}
}
EDIT 2: I finally found why this error occurs. Calling a function that dispatches something to the store will update the PrivateRoute so it will get called again:
class PrivateRouteTestComponent extends Component {
componentDidMount() {
console.log("PrivateRouteTestComponent.componentDidMount is called!");
// This doesn't cause the problem
testBackendCall();
// This causes the problem
// Because it dispatches an action to the store
// So PrivateRoute gets updated
this.props.testBackendCallThatDispatchesSomethingToTheStore();
}
render() {
return (
<div>
<button
onClick={() => {
this.props.history.push("/videos-page");
}}
>
Home
</button>
<h6>Private route test component</h6>
</div>
);
}
}