代码之家  ›  专栏  ›  技术社区  ›  Sam

未调用componentDidMount(),但仅在特定情况下调用。

  •  5
  • Sam  · 技术社区  · 7 年前

    因此,我转到我的 home ,然后 account list ,两者都不需要任何参数,我可以根据自己的喜好来回多次,没有问题。

    import react,component from'react';
    从'react router dom'导入路由、交换机和路由器;
    
    //为了简洁起见只显示一个
    
    从“.../actions/app actions”导入*为appactions;
    
    
    
    
    呈现()。{
    
    
    <DIV>
    <route exact path=“/member”组件=主页/>
    <route exact path=“/member/projects”component=项目列表/>
    <route exact path=“/member/tasks”组件=taskslist/>
    </switch>
    )(二)
    
    
    
    返回{
    }
    
    
    返回{
    
    
    
    
    
  • 它们还根据用户的屏幕分辨率加载正确的子组件
  • 这是我的projectprofilecomponent和taskprofileis pretty much identified to this.

    从“react redux”导入connect; //操作 从“./projectprofiledesktop”导入桌面; 类ProjectProfile扩展组件{ <div classname=“height-100 width-100 row row clean”> </DIV> )(二) 函数mapDispatchTopOps(调度){ 操作:BindActionCreators(ProjectProfileActions,Dispatch) }

    最奇怪的是,如果我在projectprofile和任何其他组件之间来回走动,远离taskprofile,就没有问题。我甚至可以用不同的ID点击projectprofile只有当我转到另一个带参数的组件时,它才会全部失败。我可以对taskprofile>code>做同样的操作。我可以继续用不同的ID敲击taskprofile或在taskprofile和any componentwithouta parameter and everything works fine.

    进一步的检查显示,在加载带有参数的组件后,如果我使用参数转到另一个组件,我只是不在第二个组件中点击componentdidmount()method。看起来像render()中的某个东西。method is caused an issue and preventing it from going tocomponentdidmount()。我不确定是什么问题,因为我没有发现任何错误。我在render()的顶部放置了一个debugger虽然我没有看到确切的错误,但流程告诉我一定有什么地方出错了。

    <provider store=存储> <stripeprovider apikey=“我的钥匙”> </provider>,

    
    
    
    

    我观察到的一个行为是,在加载带有参数的组件后,当我使用参数单击第二个组件时,我单击了render()method first and right after the firstcreateElement,code跳转到reactivestrumentation.debugtool.onbeginLifecycleTimer--请参见下面的屏幕截图。

    更新2:

    我还从路由中删除了我的taskprofileprojectprofile组件

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

    Home,然后Account List

    react-router

    这是我的路线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));
    

    正如你从路线上看到的,两者都是ProjectProfileTaskProfile组件需要ID。此外,两者都需要任务配置文件

    1. 进行API调用以在componentDidMount()
    2. 它们还根据用户的屏幕分辨率加载正确的子组件

    项目配置文件

    import React, { Component } from 'react'
    import { connect } from 'react-redux';
    import { bindActionCreators } from 'redux';
    
    // Actions
    import * as projectProfileActions from '../../../actions/project-profile-actions';
    
    // Components
    import Desktop from './ProjectProfileDesktop';
    import Mobile from './ProjectProfileMobile';
    
    class ProjectProfile extends Component {
    
        constructor(props) {
    
            super(props);
        };
    
        componentDidMount() {
    
            const id = this.props.match.params.id;
            this.props.actions.getData(id);
        }
    
        render() { 
    
            return (
                    <div className="height-100 width-100">
                        <div className="height-100 width-100 row row-clean">
                        {this.props.ui.isDesktop || this.props.ui.isTablet ? <Desktop />
                            : this.props.ui.isMobile ? <Mobile />
                            : null}
                        </div>
                </div>
            );
        }
    }
    
    function mapStateToProps(state) {
        return {
            ui: state.app.window
        };
    }
    
    function mapDispatchToProps(dispatch) {
    
        return {
            actions: bindActionCreators(projectProfileActions, dispatch)
        };
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(ProjectProfile);
    

    项目配置文件没有问题。我甚至可以打用不同的身份证,一切正常。只有当我去一个参数,一切正常。

    首先,然后尝试转到

    错误只是告诉我数据ProjectProfileDesktop

    进一步的检查显示,在加载了一个带有参数的组件之后,如果我转到另一个带有参数的组件,我只是不点击第二个组件中的方法。看起来有点像render()debugger呈现()

    请注意我正在使用withRouter带路由器

    App看起来像在我的index.js

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

    createElementReactInstrumentation.debugTool.onBeginLifeCycleTimer

    enter image description here

    更新2:

    反应路由器

    我也移除了/:id组件。

    组件安装()componentDidUpdate()componentWillUnmount()组件将卸载()

    或者被调用的任何其他生命周期方法,但这只发生在这种特定的情况下。

    2 回复  |  直到 7 年前
        1
  •  6
  •   Sam    7 年前

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

    我真正想分享的是我为每个未来可能经历类似行为的人所学到的经验。

    1. componentDidMount() 每次加载组件时。即使来回加载相同的组件。但你击中了 仅当您的组件首先卸载时。如果组件没有卸载,您将不会 在以后的组件使用中。所以仔细观察您的逻辑,看看如果您离开它,您的组件是否会被卸载。我认为最简单的方法就是增加 componentWillUnmount() debugger
    2. 在这个过程中做了大量的研究,看看哪里是进行API调用获取数据的最佳位置,很明显
    3. componentWillReceiveProps() ,请 componentWillUpdate() componentWillMount() https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html
    4. 也许最重要的一课是:问题的原因可能比您想象的要简单得多——通常是——而且代码中的逻辑可能是问题的原因——通常是!

        2
  •  -3
  •   Lucas Milotich    7 年前

    当组件被安装时,它只被调用一次。当您使用prop进行API调用时,我将使用componentwillreceiveprops并检查props,然后进行API调用。