Javascript componentDidMount()未被调用,但仅在特定情况下才会被调用

Javascript componentDidMount()未被调用,但仅在特定情况下才会被调用,javascript,reactjs,react-router,react-router-v4,react-router-dom,Javascript,Reactjs,React Router,React Router V4,React Router Dom,只是提醒一下:这是一个非常奇怪的问题。我会尽力把这个问题解释清楚。这是在我的ReactJs应用程序中使用React路由器发生的 我有一些组件需要来自URL的某种类型的参数。我还有不依赖于参数的组件 如果我转到不需要任何参数的组件,则不会出现任何问题 因此,我去我的主页,然后查看帐户列表,这两个列表都不需要任何参数,我可以随意来回,没有问题 但是,如果我转到一个使用参数的组件,然后尝试转到另一个使用参数的组件,我就会得到一个错误。该错误表示应该加载的组件react router未正确安装,这会引发

只是提醒一下:这是一个非常奇怪的问题。我会尽力把这个问题解释清楚。这是在我的
ReactJs
应用程序中使用
React路由器发生的

我有一些组件需要来自URL的某种类型的参数。我还有不依赖于参数的组件

如果我转到不需要任何参数的组件,则不会出现任何问题

因此,我去我的
主页
,然后查看
帐户列表
,这两个列表都不需要任何参数,我可以随意来回,没有问题

但是,如果我转到一个使用参数的组件,然后尝试转到另一个使用参数的组件,我就会得到一个错误。该错误表示应该加载的组件
react router
未正确安装,这会引发一个错误,告诉我子组件所需的数据丢失。我得到的错误很简单。他们只是说:

this.props.something是必需的,但未定义

以下是我在
App.jsx
中的路线:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Route, Switch, withRouter } from 'react-router-dom';

// Import components here
// Just showing one for brevity
import Home from '../components/home/Home';

import * as appActions from '../actions/app-actions';

class App extends Component {

   constructor(props) {

      super(props);
   }

   render() {

      return(

          <div>
              <Switch>
                 <Route exact path="/member" component={Home} />
                 <Route exact path="/member/accounts" component={Accounts} />
                 <Route exact path="/member/projects" component={ProjectsList} />
                 <Route path="/member/projects/profile/:id" component={ProjectProfile} />|
                 <Route exact path="/member/tasks" component={TasksList} />
                 <Route path="/member/tasks/profile/:id" component={TaskProfile} />
              </Switch>
          </div>
      );

   }
}

function mapStateToProps(state) {

    return {
        member: state.member.memberData
    }
}

function mapDispatchToProps(dispatch) {

    return {

        actions: bindActionCreators(appActions, dispatch)
    };
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
最奇怪的是,如果我一直在
ProjectProfile
和任何其他组件之间来回走动,并且远离
TaskProfile
,那么就没有问题了。我甚至可以用不同的ID点击
ProjectProfile
,一切正常。只有当我转到另一个带有参数的组件时,这一切才会失败。我可以对
TaskProfile
执行同样的操作。我可以用不同的ID继续点击
TaskProfile
,或者在
TaskProfile
和任何组件之间来回移动,而不需要参数,一切都正常

只有先转到
ProjectProfile
,然后再尝试转到
TaskProfile
或反之亦然,才会发生错误

错误只是告诉我,
ProjectProfileDesktop
所需的数据不存在

进一步检查表明,在加载一个带有参数的组件后,如果我转到另一个带有参数的组件,我只是没有点击第二个组件中的
componentDidMount()
方法。看起来
render()
方法中的某些内容导致了问题,并阻止它转到
componentDidMount()
。我不确定问题是什么,因为我没有得到任何错误。我在
render()
方法的顶部放置了一个
debugger
。虽然我没有看到确切的错误,但流程告诉我肯定出了问题

请注意,我正在使用路由器
。我看到了一些涉及路由器的问题,但同样地,到目前为止,我找不到任何具体的问题

我还想提及的是,我还让Stripe provider包装了我的
应用程序
组件。不确定这是否也在这个问题中起作用。以下是我的
index.js
中的
render()
的外观:

render(
   <Provider store={store}>
        <BrowserRouter history={browserHistory}>
          <StripeProvider apiKey="my_key">
              <App />
          </StripeProvider>
       </BrowserRouter>
   </Provider>,
   document.getElementById('root')
);
渲染(

更新2:

在这一点上,我确信问题不是由
react router
引起的,因为我将所需的ID硬编码到组件中,这样我就不会依赖
react router
或其他任何东西来获取它

我还从我的
TaskProfile
ProjectProfile
组件的路由中删除了
/:id
参数

我仍然得到相同的行为。因此,有东西阻止调用
componentDidMount()
方法。我还尝试
componentdiddupdate()
查看它是否被调用。我放置了
componentWillUnmount()
在这两个组件中,当我在应用程序的其他位置导航时,会调用这两个组件中的
componentWillUnmount()

因此,底线是
render()
方法中的某些东西阻止调用
componentDidMount()
或任何其他生命周期方法,但这只发生在这种特殊情况下


我非常感谢大家在这一点上的建议!!!

ComponentDidMount它只在组件挂载时被调用一次。当您使用道具进行api调用时,我会使用componentWillReceiveProps并检查道具,然后进行api调用

如果要检查流是否使用了componentDidMount,请使用console.log进行检查


问候!

一个多星期以来,我一直在为这个问题绞尽脑汁,终于解决了。诚然,在这个过程中,我认为我理解的许多概念变得更加清晰

这个错误是由于我处理“isLoading”动画逻辑的一个逻辑错误造成的——是的,就这么简单和愚蠢

我真正想在这里分享的是我为将来可能经历类似行为的每个人所学到的经验教训

  • 每次加载组件时,您都应该点击
    componentDidMount()
    。即使您来回加载同一个组件。但只有在首先卸载组件时,您才会点击
    componentDidMount()
    。如果组件未卸载,您将不会点击
    componentDidMount()
    在后续使用组件时。因此,请仔细查看您的逻辑,看看如果您离开组件,是否会卸载组件。我认为最简单的方法是添加
    componentWillUnmount()
    方法,其中包含
    调试器
    。如果您在导航离开组件时点击此方法,则意味着它正在卸载
  • 在这个过程中做了大量的研究,以确定在哪里进行API调用以获取数据的最佳位置,这一点非常清楚
    render(
       <Provider store={store}>
            <BrowserRouter history={browserHistory}>
              <StripeProvider apiKey="my_key">
                  <App />
              </StripeProvider>
           </BrowserRouter>
       </Provider>,
       document.getElementById('root')
    );