使用React Router Link,Redux和componentWillReceiveProps更新组件导致网络错误

时间:2016-08-30 18:11:06

标签: reactjs redux react-router react-redux

我正在尝试根据本教程https://github.com/reactjs/react-router/tree/master/examples/master-detail向使用redux的应用添加主详细信息,例如https://github.com/bradwestfall/CSS-Tricks-React-Series

我使用componentWillUpdate获取要更新的组件,但它导致网络错误,因为它不断地反复敲击端点。

我的容器看起来像这样:

import React from 'react';
import { connect } from 'react-redux';
import TeamMemberProfile from '../../views/team-member/team-member-profile';
import TeamMemberList from '../../views/team-member/team-member-list';
import * as teamMemberApi from '../../../api/team-member-api';
import store from '../../../store';
import { loadSearchLayout } from '../../../actions/search-layout-actions';

const TeamMemberProfileContainer = React.createClass({

  componentDidMount: function() {
    let teamMemberId = this.props.params.teamMemberId;
    teamMemberApi.getTeamMembers();
    teamMemberApi.getProfile(teamMemberId);
  },
  componentWillReceiveProps: function(nextProps) {
    let teamMemberId = this.props.params.teamMemberId;
    let teamMemberProfile = teamMemberApi.getProfileUpdate(teamMemberId);
    this.setState({
      teamMemberProfile: teamMemberProfile
    })
  },
  // add getProfileUpdate()
  render: function() {
    return (
    <div>
      <TeamMemberProfile {...this.props.profile} />
      <TeamMemberList teamMembers={this.props.teamMembers} deleteTeamMember={teamMemberApi.deleteTeamMember} />
    </div>
    );
  }
});

const mapStateToProps = function(store) {
  return {
    profile: store.teamMemberState.teamMemberProfile,
    teamMembers: store.teamMemberState.teamMembers
  };
};

export default connect(mapStateToProps)(TeamMemberProfileContainer);

我的观点:

// team-member-list.js
import React from 'react';
import { Link } from 'react-router';

// Using "Stateless Functional Components"
export default function(props) {
  return (
    <div className="data-list">

      {props.teamMembers.map(teamMember => {

        return (
          <div key={teamMember.id} className="container">
            <div className="details">
              <Link to={'/team-members/' + teamMember.id}>{teamMember.name}</Link>
            </div>
            <div className="controls">
              <button onClick={props.deleteTeamMember.bind(null, teamMember.id)} className="delete">Delete</button>
            </div>
          </div>
        );

      })}

    </div>
  );
}

// team-member-profile.js
import React from 'react';
import { Link } from 'react-router';

// Using "Stateless Functional Components"
export default function(props) {
  return (
    <div className="container">
      <img className="col-md-1" src={props.image} />
      <div className="details">
        <h1>{props.name}</h1>
        <p>{props.title}</p>
        <p>{props.blurb}</p>
      </div>
    </div>
  );
}

以下是我的行动:

import * as types from '../actions/action-types';

export function getTeamMembersSuccess(teamMembers) {
  return {
    type: types.GET_TEAM_MEMBERS_SUCCESS,
    teamMembers
  };
}

export function deleteTeamMemberSuccess(teamMemberId) {
  return {
    type: types.DELETE_TEAM_MEMBER_SUCCESS,
    teamMemberId
  };
}

export function teamMemberProfileSuccess(teamMemberProfile) {
  return {
    type: types.TEAM_MEMBER_PROFILE_SUCCESS,
    teamMemberProfile
  };
}

export function teamMemberProfileSuccessUpdate(teamMemberProfile) {
  return {
    type: types.TEAM_MEMBER_PROFILE_SUCCESS_UPDATE,
    teamMemberProfileSuccessUpdate
  };
}

我的减速机:

import * as types from '../actions/action-types';
import _ from 'lodash';

const initialState = {
  teamMembers: [],
  teamMemberProfile: {}
};

const teamMemberReducer = function(state = initialState, action) {

  switch(action.type) {

    case types.GET_TEAM_MEMBERS_SUCCESS:
      return Object.assign({}, state, { teamMembers: action.teamMembers });

    case types.DELETE_TEAM_MEMBER_SUCCESS:

      // Use lodash to create a new teamMember array without the teamMember we want to remove
      const newUsers = _.filter(state.teamMembers, teamMember => teamMember.id != action.teamMemberId);
      return Object.assign({}, state, { teamMembers: newUsers });

    case types.TEAM_MEMBER_PROFILE_SUCCESS:
      return Object.assign({}, state, { teamMemberProfile: action.teamMemberProfile });

    case types.TEAM_MEMBER_PROFILE_SUCCESS_UPDATE:
      return Object.assign({}, state, { teamMemberProfileSuccessUpdate: action.teamMemberProfileSuccessUpdate});

  }

  return state;

}

export default teamMemberReducer;

API端点:

import axios from 'axios';
import store from '../store';
import { getTeamMembersSuccess, deleteTeamMemberSuccess, teamMemberProfileSuccess, teamMemberProfileSuccessUpdate } from '../actions/team-member-actions';

/**
 * Get all teamMembers
 */

export function getTeamMembers() {
  return axios.get('http://localhost:3001/team-members')
    .then(response => {
      store.dispatch(getTeamMembersSuccess(response.data));
      return response;
    });
}

/**
 * Search teamMembers
 */

export function searchTeamMembers(query = '') {
  return axios.get('http://localhost:3001/team-members?q='+ query)
    .then(response => {
      store.dispatch(getTeamMembersSuccess(response.data));
      return response;
    });
}

/**
 * Delete a teamMember
 */

export function deleteTeamMember(teamMemberId) {
  return axios.delete('http://localhost:3001/team-members/' + teamMemberId)
    .then(response => {
      store.dispatch(deleteTeamMemberSuccess(teamMemberId));
      return response;
    });
}

/**
 * getProfile() is much more complex because it has to make
 * three XHR requests to get all the profile info.
 */

export function getProfile(teamMemberId) {

  // Start with an empty profile object and build it up
  // from multiple XHR requests.
  let profile = {};

  // Get the teamMember data from our local database.
  return axios.get('http://localhost:3001/team-members/' + teamMemberId)
    .then(response => {

      let teamMember = response.data;
      profile.name = teamMember.name;
      profile.title = teamMember.title;
      profile.blurb = teamMember.blurb;
      profile.image = teamMember.image;

      store.dispatch(teamMemberProfileSuccess(profile));
      return;
    });

}

export function getProfileUpdate(teamMemberId) {

  // Start with an empty profile object and build it up
  // from multiple XHR requests.
  let profile = {};

  // Get the teamMember data from our local database.
  return axios.get('http://localhost:3001/team-members/' + teamMemberId)
    .then(response => {

      let teamMember = response.data;
      profile.name = teamMember.name;
      profile.title = teamMember.title;
      profile.blurb = teamMember.blurb;
      profile.image = teamMember.image;

      store.dispatch(teamMemberProfileSuccess(profile));
      return;
    });

}

0 个答案:

没有答案