React Router master-detail:子组件在页面刷新之前不会呈现新视图

时间:2016-07-25 20:44:11

标签: reactjs react-router url-routing nested-routes react-router-component

我正在创建一个主要细节导航,就像这里的例子the react router example;

一样

我有一个容器组件OneCheckpointContainer,它呈现导航面板CheckpointNav(链接)和数据组件OneCheckpointData(这个人在加载时获取数据,并呈现{{ 1}}。

当我点击OneCheckpointView中的一个链接时,除了浏览器中的URL发生更改外,没有任何反应。直到我刷新页面才会获取新数据,然后在子视图中呈现新组件。 (也没有错误)

我不确定这个错误是否因为子组件还负责获取数据以及视图。

以下是设置路线的方法:

CheckpointNav

OneCheckpointContainer

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

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

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;

OneCheckpointData 除非我刷新

,否则不会获取新数据并呈现新数据
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;

**我遗漏了OneCheckpointView,因为它应该是无关紧要的**

4 个答案:

答案 0 :(得分:6)

在这种情况下,您可以将道具作为summaryId功能的参数,您可以在loadCheckpoing(props)上发送新道具,如下所示

componentWillReceiveProps

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

答案 1 :(得分:1)

问题是您的组件仅在安装之前获取数据。这仅在第一次显示时有效。这些组件还需要在收到新属性时获取数据,例如导航到新位置后,路由器中的ID。

为了做到这一点,最简单的方法是添加一个componentWillReceiveProps,用于比较之前的道具和新道具,并在需要时提取新数据。

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

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

答案 2 :(得分:1)

我认为这是因为您在componentwillMount中调用了函数loadcheckpoints。这只在组件生命周期中调用一次。 由于当您单击导航栏中的链接时已经安装了该组件,因此不会调用compoenntwillmount。因此,不会进行数据提取。

我猜你应该尝试以下方法。 CheckpointNav中链接的onclick函数应该从OneCheckpointContainer传递。加载的数据应该在容器中设置为state,它将数据作为道具传递给OneCheckpointData。

答案 3 :(得分:1)

诊断的两个步骤:

  1. 检查每次点击其他链接时是否调用了方法loadCheckpoint。只需在该方法中留下console.log(new Date().toLocaleTimeString())之类的一行

  2. 即可
  3. 如果第1步成功,请检查此部分中是否存在this引用问题: (data) => { this.setState({ checkpoint: data }); }

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