我有以下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);
当组件呈现为先前组件时, state.user_positions
= {}
是提交state.user_positions
的表单。在渲染SkillPage组件之后,将填充state.user_positions,我在Redux chrome扩展中验证了该文件。
问题是这个SkillPage组件不会自动重新渲染。我希望组件自动检测到state.user_positions
已更改并重新运行componentDidMount,然后发送loadJobTitleSkills()
。
我在这里做错了什么?每当修改state.user_positions时,为什么我的组件不会重新渲染?
userPositionReducer.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;
}
}
jobTitleSkillsReducer.js:
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;
}
}
我能够把它带到&#34;工作&#34;通过将以下内容添加到我的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));
}
}
这感觉超级hacky。有更好的方法吗?
Working with this added:
componentWillReceiveProps(nextProps) {
if (nextProps.user_positions && nextProps.user_positions.length > 0) {
if (this.props.user_positions[0] !== nextProps.user_positions[0]) {
this.props.dispatch(loadJobTitleSkills(nextProps.user_positions[0].job_title_id));
}
}
}
这个解决方案仍然感觉超级黑客。
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);
});
};
}
UserPositionActions.js
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);
});
};
}
答案 0 :(得分:5)
ComponentDidMount
lifeCycle函数仅在组件安装时执行一次。你想要的是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));
}
}