javascript - React history.push laddar om komponenten. Vill att den ska laddas bara en gång
När jag omdirigerar efter att komponenten har laddats med history.push - renderas min komponent igen. Detta gör att componentDidMount()-funktionen körs två gånger.
Här är ett förenklat utdrag av en av mina komponenter. Jag vill att componentDidMount() ska köras bara en gång - och det fungerar som förväntat utan history.push. Men när jag lägger till history.push - laddas den två gånger. (Samma händer om jag använder Redirect från 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 />;
}
}
Konsol :
componentDidMount
componentDidMount
Skulle älska att hitta ett sätt att få detta att köras bara en gång.
Redigera: Tack för svaren allihopa. Jag kommer att posta ett kort kodexempel och sedan posta en Fiddle om en stund.
--- Uppdatering:
Jag använder React-Router. Jag bygger historiken (tillsammans med några andra tjänster) i filen configureServices.ts.
// configureServices.ts
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
Min index.ts ser ut så här:
import { history } from "./configureServices";
ReactDOM.render(
<Provider {...stores}>
<AppComponent history={history} />
</Provider>,
document.getElementById("root") );
Och min AppComponent som har alla rutterna ser ut så här:
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>
);
}
}
Tack igen för att du hjälpte mig med detta.
Svar #1
Det finns ett par saker som kan få din komponent att montera om.
- Om React-komponentträdet ovanför denna komponent ändras. Detta kan orsakas av något som att ha flera
Route-komponenter som visar denna komponent, men sökvägen ändras från en till en annan. Även om samma komponent slutligen visas, ändrades denRoute-komponent som matchades. - Om nyckeln för denna komponent ändrades. Om du gör något som att använda slumpmässigt genererade nycklar, eller använda arrayindex som nycklar och ordna om element, då kommer du att se komponenter monteras om.
Svar #2
Jag ville uppdatera frågan eftersom jag listade ut det. Jag kallade history.replace(explore) i componentDidMount() - vilket (av skäl jag inte riktigt förstår) - fick react-komponentträdet ovanför denna komponent att förändras som Matt H nämnde. Jag slutade med att använda Redirect från react-router-dom och returnerade omdirigeringen i render. Som:
render() {
return <Redirect to={explore} />;
}
Så, istället för att göra alla samtal i componentDidMount() och omdirigera i den funktionen också, gjorde jag API-anropen i componentDidMount() och använde render för att omdirigera. Glad att det fungerade och tack till er alla för att ni svarade på min fråga.
