问题是下拉式组件在首次加载时在组件视图上未显示任何选项,但在重新加载后显示。我从商店获取商店数据作为响应,但组件未获取数据我在下面放置了控制台日志,我从mapStateToProps的控制台日志中获取数据,但是我在componentDidMount的控制台日志中发现了一个空数组,上面写着this.props.skills.reducer或组件中的代码是否有问题?
以下是减速器:
技能减少者:
const skillInitialState = {
skillList: []
}
const skillReducer = (state = skillInitialState, action) => {
switch (action.type) {
case 'GET_SKILLS':
console.log('the reducer state is ......$$$$$$$$$$$$ ', state)
console.log('the skillsssss.....%%%%%%****', action.payload)
return {
...state,
skillList: action.payload
}
default:
return state
}
}
export default skillReducer
下面是组件:
import React from 'react';
import Select from 'react-select';
import { connect } from 'react-redux';
import { startGetSkills, startGetEmployeeSkills } from "../../action/index.js";
class MultiSelect extends React.Component {
constructor() {
super()
this.state = {
options: [],
selectedOptions: [],
}
}
componentDidMount() {
const skillOptions = []
this.props.startGetSkills()
this.props.startGetEmployeeSkills()
console.log('The skill options are .......', this.props.skills)
this.props.skills.forEach((skill) => {
console.log('The skills are ......', skill)
skillOptions.push({
value: skill._id,
label: skill.skillName.charAt(0).toUpperCase() + skill.skillName.slice(1),
_id: skill._id
})
})
this.setState({ options: skillOptions })
this.setState({ selectedOptions: this.props.selectSkill })
}
render() {
const { skills, heading, index } = this.props
const { options } = this.state
return (
<div>
<label> {heading} </label>
<Select
isMulti={true}
defaultValue={this.props.selectSkill}
value={this.state.selectedOptions}
options={options}
onChange={(e) => {
this.setState({ selectedOptions: e })
this.props.handleSkillChange(e)
}}
/>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
startGetSkills: () => {
dispatch(startGetSkills())
},
startGetEmployeeSkills: () => {
dispatch(startGetEmployeeSkills())
}
}
}
const mapStateToProps = (state) => {
console.log('the skills mapstateToprops are.......',state.skill.skillList)
return {
skills: state.skill.skillList,
employees: state.employee,
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MultiSelect)
UserSkills动作
import axios from '../../src/config/axios';
import { GET_SKILLS } from './types';
export const getSkills = (skills) => {
return {
type: GET_SKILLS,
payload: skills
}
}
export const startGetSkills = () => {
return (dispatch) => {
axios.get(`/users/skills`, {
headers: {
'x-auth': localStorage.getItem('token')
}
})
.then((response) => {
console.log('the skills... response is .....', response.data)
dispatch(getSkills(response.data))
})
.catch(err => console.log(err))
}
}
答案 0 :(得分:0)
正在componentDidMount
中触发分派动作,此触发后,您的代码将移至下一行。
目前,当您打印console.log('The skill options are .......', this.props.skills)
时,API调用仍在进行,因此商店更新尚未发生。出于相同的原因,技能变量为[]
。
现在,一旦您的API完成,它将更新您的redux存储。您拥有的组件应该能够在componentDidUpdate
函数中接收更新的数据。
componentDidUpdate(prevProps) {
console.log(this.props); // updated skills should be available
}
现在,由于这里有数据,您可以通过此功能更新状态。
除此答案外,仅提供少量反馈,可帮助您遵循良好做法。 您最好不要将值从商店复制到您的州。它使您的代码确实令人迷惑并且难以调试。
有关更多详细信息,请阅读here。
通过您的代码,将技能完全转移到redux存储并创建无状态组件可以轻松实现相同目的。
答案 1 :(得分:0)
componentDidMount
仅在第一次调用时,然后您将分派动作以获取技能,因此它将作为道具传递给组件。因此,您应该使用的生命周期方法是componentDidUpdate
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.skills !== prevProps.skills) {
// update the state here with updated data
}
}
答案 2 :(得分:0)
啊哈。我明白了您显然会在componentDidmount中得到一个空数组。您将必须在componentWillrecieveProps中编写以下代码。调用动作后,将需要一些时间来通过reducer更新状态。因此,紧接动作调用后的行将不会使用适当的道具进行更新。
this.props.skills.forEach((skill) => {
console.log('The skills are ......', skill)
skillOptions.push({
value: skill._id,
label: skill.skillName.charAt(0).toUpperCase() + skill.skillName.slice(1),
_id: skill._id
})
})
this.setState({ options: skillOptions })
this.setState({ selectedOptions: this.props.selectSkill })