When redirecting after component loads using history.push - my component is rendered again. Causing componentDidMount()
function to run twice.
Here's a simplified snippet of one of my components.
I want the componentDidMount()
to run only once - and it works as expected without the history.push
. But when i add the history.push
- it loads twice. (Same happens if i use Redirect
from react-router
)
import * as React from "react";
import { history } from "../../configureServices";
import { explore } from "../../routes";
export class WelcomeComponent extends React.Component<object, object> {
componentDidMount() {
// tslint:disable-next-line:no-console
console.log("componentDidMount");
history.replace(explore);
}
render() {
return <div />;
}
}
Console:
componentDidMount
componentDidMount
Would love to find a way to have this run only once.
Edit: Thank you for the responses everyone. I'm going to post a quick code snippet and then post a Fiddle in a bit.
--- Update:
I am using React-Router. I build the history (along with some other services) in the configureServices.ts file.
// configureServices.ts
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
My index.ts looks like this:
import { history } from "./configureServices";
ReactDOM.render(
<Provider {...stores}>
<AppComponent history={history} />
</Provider>,
document.getElementById("root") );
And my AppComponent which has all the routes looks like this:
import { History } from "history";
import { Route, Switch } from "react-router-dom";
import { Router } from "react-router-dom";
import * as Routes from "../../routes";
...
// Import Components
...
interface Props {
history: History;
...
}
export class AppComponent extends React.Component<Props, {}> {
componentDidMount() {
this.props.authStore && this.props.authStore.authenticate();
}
render() {
return (
<Router history={this.props.history}>
// For toasts, please ignore for this example
<ToastProvider
placement={toastPlacement}
autoDismissTimeout={toastDismissTimeout}
>
// Main App Div = Navbar + Components
<div className="font-sans flex flex-col h-full text-phi-green-munsell bg-phi-gunmetal-rich-dark">
<NavBarComponent />
// This is where the routes are
<div className="container mx-auto p-2 md:p-3 lg:p-4 justify-start">
<Switch>
<Route
exact={true}
path={Routes.homePage}
component={HomepageContainer}
/>
<Route
exact={true}
path={Routes.logOut}
component={LogOutContainer}
/>
<Route
exact={true}
path={Routes.welcome}
component={WelcomeContainer}
/>
<Route
path={Routes.explore}
component={ExploreComponent}
/>
<Route
path={Routes.searchResults}
component={SearchResultsComponent}
/>
</Switch>
</div>
<Footer />
<DevTools position={mobxDevToolsPosition} />
</div>
</ToastProvider>
</Router>
);
}
}
Thank you again for helping me with this.
How do you refresh a page without reloading in React? Method 1: Refresh a Page Using JavaScript window. location. reload(false); This method takes an optional parameter which by default is set to false.
Calling history. push() inside of a component seems to cause the entire react component to unmount and remount; causing pointless remote service calls.
push(`/route`); This will clear the history and change for a new one. Save this answer.
Does react-router dom reload the page? react-router-dom allows us to navigate through different pages on our app with/without refreshing the entire component. By default, BrowserRouter in react-router-dom will not refresh the entire page.
There are a couple of things that could cause your component to remount.
Route
components which display this component, but the path changes from one to the other. Even though the same component is ultimately displayed, the Route
component which was matched changed.I wanted to update the question since I figured it out. I was calling history.replace(explore)
in componentDidMount()
- which (for reasons I don't understand well) - was causing the react component tree above this component to change as Matt H mentioned. I ended up using Redirect
from react-router-dom
and returning the redirect in render. Like:
render() {
return <Redirect to={explore} />;
}
So, I instead of making all calls in componentDidMount() and redirecting in that function as well. I made the api calls in componentDidMount() and used render to redirect. Happy it worked and thank you all for responding to my question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With