Reactjs 在React Redux中更改道具后,不会再次调度操作

Reactjs 在React Redux中更改道具后,不会再次调度操作,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我有以下反应组件: import React from 'react'; import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import {loadJobTitleSkills} from '../../actions/jobTitleSkillsActions'; import SkillList from './SkillList'; class SkillPage extends React.

我有以下反应组件:

import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {loadJobTitleSkills} from '../../actions/jobTitleSkillsActions';
import SkillList from './SkillList';

class SkillPage extends React.Component {

  componentDidMount() {
    if (this.props.user_positions[0]) {
      this.props.dispatch(loadJobTitleSkills(this.props.user_positions[0].job_title_id));
    }
  }

  render() {
    return (
      <div>
        <SkillList skills={this.props.job_title_skills} />
      </div>
    );
  }
}

SkillPage.propTypes = {
  job_title_skills: PropTypes.array.isRequired,
  user_positions: PropTypes.array.isRequired,
};

const mapStateToProps = state => {
  return {
    job_title_skills: state.job_title_skills,
    user_positions: state.user_positions
  };
};

export default connect(mapStateToProps)(SkillPage);
jobTitleSkillsReducer.js:

import * as types from '../actions/actionTypes';

const initialState = {}

export default function userPositionReducer(state = initialState, action) {
  switch (action.type) {
    case types.CREATE_USERPOSITION_SUCCESS:
      return action.user_position
    case types.LOAD_USERPOSITION_SUCCESS:
      return action.user_positions
    default:
      return state;
  }
}
import * as types from '../actions/actionTypes';

const initialState = []

export default function jobTitleSkillsReducer(state = initialState, action) {
  switch (action.type) {
    case types.LOAD_JOBTITLESKILLS_SUCCESS:
     return action.job_title_skills
    default:
      return state;
  }
}
使现代化 通过向SkillPage组件中添加以下内容并删除componentDidMount,我可以让它正常工作

  componentDidUpdate() {
    if (this.props.user_positions[0] && this.props.job_title_skills.length === 0) {
      this.props.dispatch(loadJobTitleSkills(this.props.user_positions[0].job_title_id));
    }
  }
这感觉非常粗糙。有更好的方法吗

更新2 这个解决方案仍然让人感觉非常粗糙

更新3-添加操作创建者 jobTitleSkillsActions.js

import * as types from './actionTypes';
import JobTitleSkillsApi from '../api/JobTitleSkillsApi';

export function loadJobTitleSkillsSuccess(job_title_skills) {
  return {type: types.LOAD_JOBTITLESKILLS_SUCCESS, job_title_skills};
}

export function loadJobTitleSkills(job_title_id) {
  return function(dispatch) {
    return JobTitleSkillsApi.getAllJobTitleSkills(job_title_id).then(skills => {
      dispatch(loadJobTitleSkillsSuccess(skills));
    }).catch(error => {
      throw(error);
    });
  };
}
import * as types from './actionTypes';
import userPositionsApi from '../api/UserPositionsApi';

export function createUserPositionSuccess(user_position) {
  return {type: types.CREATE_USERPOSITION_SUCCESS, user_position};
}

export function loadUserPositionSuccess(user_positions) {
  return {type: types.LOAD_USERPOSITION_SUCCESS, user_positions};
}

export function loadUserPositions() {
  // console.log('actions: loadUserPosition')
  return function(dispatch) {
    return userPositionsApi.getAllUserPositions().then(user_positions => {
      dispatch(loadUserPositionSuccess(user_positions));
    }).catch(error => {
      throw(error);
    });
  };
}

export function createUserPosition(user_position) {
  // console.log('actions: createUserPosition')
  return function (dispatch) {
    return userPositionsApi.createUserPosition(user_position).then(responseUserPosition => {
      dispatch(createUserPositionSuccess(responseUserPosition));
      return responseUserPosition;
    }).catch(error => {
      throw(error);
    });
  };
}
UserPositionActions.js

import * as types from './actionTypes';
import JobTitleSkillsApi from '../api/JobTitleSkillsApi';

export function loadJobTitleSkillsSuccess(job_title_skills) {
  return {type: types.LOAD_JOBTITLESKILLS_SUCCESS, job_title_skills};
}

export function loadJobTitleSkills(job_title_id) {
  return function(dispatch) {
    return JobTitleSkillsApi.getAllJobTitleSkills(job_title_id).then(skills => {
      dispatch(loadJobTitleSkillsSuccess(skills));
    }).catch(error => {
      throw(error);
    });
  };
}
import * as types from './actionTypes';
import userPositionsApi from '../api/UserPositionsApi';

export function createUserPositionSuccess(user_position) {
  return {type: types.CREATE_USERPOSITION_SUCCESS, user_position};
}

export function loadUserPositionSuccess(user_positions) {
  return {type: types.LOAD_USERPOSITION_SUCCESS, user_positions};
}

export function loadUserPositions() {
  // console.log('actions: loadUserPosition')
  return function(dispatch) {
    return userPositionsApi.getAllUserPositions().then(user_positions => {
      dispatch(loadUserPositionSuccess(user_positions));
    }).catch(error => {
      throw(error);
    });
  };
}

export function createUserPosition(user_position) {
  // console.log('actions: createUserPosition')
  return function (dispatch) {
    return userPositionsApi.createUserPosition(user_position).then(responseUserPosition => {
      dispatch(createUserPositionSuccess(responseUserPosition));
      return responseUserPosition;
    }).catch(error => {
      throw(error);
    });
  };
}
ComponentDidMount生命周期功能仅在组件装载时执行一次。您需要的是componentWillReceiveProps函数,它也会在每次道具更改时执行

这样做

componentDidMount() {
    if (this.props.user_positions[0] ) {
      this.props.dispatch(loadJobTitleSkills(this.props.user_positions[0].job_title_id));
    }
  }
componentWillReceiveProps(nextProps) {

     if (this.props.user_positions[0] !== nextProps.userPositions[0]) {
      this.props.dispatch(loadJobTitleSkills(this.props.user_positions[0].job_title_id));
    }
}
ComponentDidMount生命周期功能仅在组件装载时执行一次。您需要的是componentWillReceiveProps函数,它也会在每次道具更改时执行

这样做

componentDidMount() {
    if (this.props.user_positions[0] ) {
      this.props.dispatch(loadJobTitleSkills(this.props.user_positions[0].job_title_id));
    }
  }
componentWillReceiveProps(nextProps) {

     if (this.props.user_positions[0] !== nextProps.userPositions[0]) {
      this.props.dispatch(loadJobTitleSkills(this.props.user_positions[0].job_title_id));
    }
}

如果我将分派移到componentDidUpdate中,它会工作,但会在一个呈现/查询循环中持续不断。我看到您的还原程序只是从操作返回值,如return action.job\u title\u skills。你是如何构造动作对象的?你的动作创造者长什么样?如果您直接在action creator中修改现有数组,然后将其添加到action中,那么您永远不会真正创建新的数组引用,connect会认为没有任何更改。@markerikson刚刚添加了action creator,这有帮助吗?有一点。看起来这些值来自API,因此您不会意外地重复使用它们。重新阅读你的问题,看起来@Shubham Khatri的答案是正确的。主要的问题是,您希望componentDidMount运行两次,而这不会-在创建和附加组件时,它只运行一次。如果我将调度移到componentDidUpdate中,那么它可以工作,但它会在呈现/查询循环中继续运行,永远不会结束。我看到您的还原程序只是从操作返回值,比如返回行动、工作、头衔、技能。你是如何构造动作对象的?你的动作创造者长什么样?如果您直接在action creator中修改现有数组,然后将其添加到action中,那么您永远不会真正创建新的数组引用,connect会认为没有任何更改。@markerikson刚刚添加了action creator,这有帮助吗?有一点。看起来这些值来自API,因此您不会意外地重复使用它们。重新阅读你的问题,看起来@Shubham Khatri的答案是正确的。主要问题是,您希望componentDidMount运行两次,而这不会-在创建和附加组件时,它只运行一次。仅供参考,错误w未处理的拒绝类型错误:无法读取undefinedok的属性“0”。我能够使其工作,但修复了几个输入错误,添加到问题中。。。这真的是应对这种情况的正确方法吗?是的,这就是解决问题的方法。此外,你可以编辑我的答案,打字你纠正,也考虑接受答案,如果它HeleDFY,那个错误W未处理的拒绝类型错误:不能读取属性“0”的未定义的OK,我能够使它工作,但固定一对夫妇打字,添加到问题…这真的是应对这种情况的正确方法吗?是的,这就是解决问题的方法。此外,你可以编辑我的答案,打字你纠正,也考虑接受答案,如果它帮助