3

ここの例と同じように、マスター/詳細ナビゲーションを作成しています 反応ルーターの例;

OneCheckpointContainerナビゲーション パネルCheckpointNav(リンク)をレンダリングするコンテナ コンポーネントと、データ コンポーネントOneCheckpointData(この男はロード時にデータをフェッチし、OneCheckpointView.

リンクの 1 つをクリックしてCheckpointNavも、ブラウザーの URL が変更される以外は何も起こりません。新しいデータがフェッチされ、新しいコンポーネントが子ビューにレンダリングされるのは、ページを更新するまでではありません。(エラーもありません)

このバグが、子コンポーネントがビューだけでなくデータのフェッチも担当しているためかどうかはわかりません。

ルートを設定する方法は次のとおりです。

  <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 は無関係であるため省略しました **

4

4 に答える 4

1

問題は、コンポーネントがマウント前にのみデータを取得していることです。これは、最初に表示されたときにのみ機能します。これらのコンポーネントは、新しいプロパティ (新しい場所に移動した後にルーターから ID など) を受け取るたびに、データを取得する必要もあります。

そのための最も簡単な方法はcomponentWillReceiveProps、以前の props を新しい props と比較し、必要に応じて新しいデータを取得する a を追加することです。

別の方法として、ルート設定にハンドラーを追加してonEnter、ルートが変更されるたびにデータを取得する方法があります。

この質問の回答を確認して、両方のアプローチの例を確認してください。

于 2016-08-17T13:15:06.307 に答える
1

診断への 2 つのステップ:

  1. loadCheckpoint別のリンクをクリックするたびにメソッドが呼び出されたかどうかを確認します。console.log(new Date().toLocaleTimeString())その方法のように1行残すだけです

  2. ステップ 1 が成功した場合は、thisこの部分に参照の問題 があるかどうかを確認します。 (data) => { this.setState({ checkpoint: data }); }

ところで、メソッドに ajax 呼び出しを入れた方がよいでしょうcomponentDidMount。参照: https://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount

于 2016-08-19T09:54:44.827 に答える