React history.push重新加载组件。希望它只加载一次

时间:2019-01-29 17:13:26

标签: javascript reactjs react-router

在使用history.push加载组件后进行重定向时-我的组件再次呈现。使componentDidMount()函数运行两次。

这是我的组件之一的简化​​片段。 我希望componentDidMount()仅运行一次-并且它可以按预期运行而无需history.push。但是,当我添加history.push时,它将加载两次。 (如果我使用Redirect中的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 />;
  }
}

控制台:

componentDidMount
componentDidMount

很乐意找到一种方法,使其只运行一次。

编辑:谢谢大家的答复。我将发布一个快速的代码段,然后再发布一个小提琴。

---更新:

我正在使用React-Router。我在configureServices.ts文件中建立了历史记录(以及其他一些服务)。

// configureServices.ts
import { createBrowserHistory } from "history";

export const history = createBrowserHistory();

我的index.ts看起来像这样:

import { history } from "./configureServices";

ReactDOM.render( 
  <Provider {...stores}> 
<AppComponent history={history} /> 
  </Provider>, 
document.getElementById("root") );

具有所有路由的AppComponent看起来像这样:

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

再次感谢您为我提供帮助。

2 个答案:

答案 0 :(得分:0)

有几件事可能会导致您的组件重新安装。

  1. 如果该组件上方的react组件树发生更改。这可能是由于具有多个显示该组件的Route组件而引起的,但是路径从一个更改为另一个。即使最终显示了相同的组件,匹配的Route组件也发生了更改。
  2. 此组件的键是否已更改。如果您正在执行诸如使用随机生成的键或对键和数组元素进行数组索引之类的操作,那么您将看到重新安装组件。

答案 1 :(得分:0)

自从我想出这个问题后,我想更新这个问题。我正在history.replace(explore)中调用componentDidMount()(由于我不太了解的原因),导致该组件上方的react组件树发生了变化,如Matt H所述。我最终使用了Redirect中的react-router-dom,并在render中返回了重定向。喜欢:

render() {
    return <Redirect to={explore} />;
  }

因此,我不是在componentDidMount()中进行所有调用,而是在该函数中进行重定向。我在componentDidMount()中进行了api调用,并使用render进行重定向。一切顺利,并感谢大家回答我的问题。