2

我正在创建一个主 - 细节导航,就像这里的示例the react router example;React Router master-detail:在刷新页面之前,children组件不会呈现新视图

我有一个容器组件OneCheckpointContainer,这使得导航面板CheckpointNav(链接),和数据分量OneCheckpointData(根据负荷这个人去抓取数据,并呈现OneCheckpointView

当我点击链接中的一个在CheckpointNav中除浏览器中的URL发生变化外,没有任何事情发生,直到我刷新页面以获取新数据,然后在子视图中呈现一个新组件(也没有错误)

I我不确定这个bug是否是因为子组件也负责提取数据以及vie W上。

这里是我有路线设置:

<Route path="/modules/:id" component={OneCheckpointContainer}> 
    <Route path="/modules/:id/checkpoints/:cp_id" component={OneCheckpointData} /> 
    </Route> 

OneCheckpointContainer

import React from 'react'; 
import CheckpointNav from './CheckpointNav'; 

class OneCheckpointContainer extends React.Component { 
    constructor(props, context) { 
    super(props, context); 

    this.state = { 
     checkpoints: null, 
     user: null 
    }; 

    } 

    componentWillMount() { 
    this.loadCheckpoints(); 
    this.context.getUser((data) => this.setState({ user: data })); 
    } 

    loadCheckpoints() { 
    $.ajax({ 
     url: `/api/v1/modules/student/${this.props.params.id}/checkpoints`, 
     method: 'GET', 
    }).done((data) => { 
     this.setState({ checkpoints: data }); 
    }); 
    } 

    render() { 
    return (
     <div> 
     <div className="col-xs-3"> 
      <CheckpointNav mid={this.props.params.id} checkpoints={this.state.checkpoints} /> 
     </div> 
     <div className="col-xs-9"> 
      { this.props.children || <div>No Children Yet</div>} 
     </div> 
     </div> 
    ) 
    } 
} 

OneCheckpointContainer.displayName = OneCheckpointContainer; 

OneCheckpointContainer.contextTypes = { 
    getUser: React.PropTypes.func.isRequired 
}; 

export default OneCheckpointContainer; 

这里是CheckpointNav虽然我不相信错误是在这里:

import React from 'react'; 
import NavLink from '../widgets/NavLink'; 

const CheckpointNav = (props) => { 
    const checkpointList = props.checkpoints && props.checkpoints.length > 0 ? 
    props.checkpoints.map((item) => { 
     return <li key={item.cp._id} className="list-group-item"> 
     <NavLink className="nav-link" to={"/modules/" + props.mid + "/checkpoints/" + item.cp._id}> 
     { item.cp.title}</NavLink></li> 
    }) : <div>No CPS</div>; 
    return (
    <div className="card one-module-card"> 
     <div className="card-block modules-card-body"> 
     <ul className="list-group tags-group"> 
      { checkpointList } 
      <li className="list-group-item new-cp"><NavLink className="" 
      to={'/post/checkpoint/' + props.mid} 
      > 
      New Checkpoint 
      </NavLink></li> 
     </ul> 
     </div> 
    </div> 
); 

}; 

export default CheckpointNav; 

OneCheckpointData 没有获取新的数据并呈现新的,除非我刷新

import React from 'react'; 
import CheckpointView from './CheckpointView'; 

class OneCheckpointData extends React.Component { 
    constructor(props, context) { 
    super(props, context); 

    this.state = { 
     checkpoint: null, 
     user: null 
    }; 

    } 

    componentWillMount() { 
    this.loadCheckpoint(); 
    this.context.getUser((data) => this.setState({ user: data })); 
    } 

    loadCheckpoint() { 
    $.ajax({ 
     url: `/api/v1/modules/three/cp/${this.props.params.cp_id}`, 
     method: 'GET', 
    }).done((data) => { 
     this.setState({ checkpoint: data }); 
    }); 
    } 

    render() { 
    return this.state.checkpoint ? <CheckpointView user={this.state.user} checkpoint={this.state.checkpoint} /> : null; 
    } 
} 

OneCheckpointData.displayName = OneCheckpointData; 

OneCheckpointData.contextTypes = { 
    getUser: React.PropTypes.func.isRequired 
}; 

export default OneCheckpointData; 

**我已经离开了OneCheckpointView因为它应该是irrelavant **

回答

5

在,这种情况下,你可以得到的道具为loadCheckpoing(props)函数的参数,你可以把在componentWillReceiveProps的新道具,就像下面

componentWillMount(this.props) { 
    this.loadCheckpoint(this.props); 
} 

componentWillReceiveProps(nextprops) { 
    this.loadCheckpoint(nextprops); 
} 

loadCheckpoint(props) { 
    this.context.getUser((data) => this.setState({ user: data })); 
    $.ajax({ 
    url: `/api/v1/modules/three/cp/${props.params.cp_id}`, //please check i have replace the this.props to props as we have props as a parameter 
    method: 'GET', 
    }).done((data) => { 
    this.setState({ checkpoint: data }); 
    }); 
} 

,我会更喜欢使用react- redux或回流库来处理您的ajax数据查询,但我提议的解决方案应该为您完成这项工作。

+0

我想我明白你要做什么,但是你不能将this.props作为参数传递给componentWillMount – fresh5447

1

的问题是,您的组件仅在安装前获取数据。这只在第一次显示时才起作用。这些组件每当他们收到新的属性时也需要获取他们的数据,例如导航到新位置后,从路由器获取ID。

为了做到这一点,最简单的方法是添加一个componentWillReceiveProps,将以前的道具与新道具进行比较,并根据需要提取新数据。

另一种方法是在路由配置中添加一个onEnter处理程序,以在路由发生更改时获取数据。

查看this question's answers查看两种方法的示例。

1

我想这是因为你已经调用了componentwillMount中的函数loadcheckpoints。这仅在组件生命周期中被调用一次。 由于单击导航栏中的链接时组件已装载,因此不会调用compoenntwillmount。因此,不会发生数据提取。

我想你应该尝试下面的方法。 CheckpointNav中的链接的onclick函数应该从OneCheckpointContainer传递。 loadeddata应该设置为在容器中的状态,它将以道具的形式将数据传递给OneCheckpointData。

1

两个步骤来诊断:

  1. 检查是否你的方法,当你点击不同的链接loadCheckpoint被称为每次。只要留下这样一行console.log(new Date().toLocaleTimeString())该方法

  2. 如果步骤1成功,然后检查是否有这部分this参考问题: (data) => { this.setState({ checkpoint: data }); }

顺便说一句,你最好把AJAX请拨打componentDidMount方法。请参阅:https://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount