我具有要在其中搜索用户列表的组件。我遇到的问题是渲染前未调用我的this.state.employees。我正在使用componentDidMount来获取我的员工列表,请参见下文:
componentDidMount() {
if (!!this.props.employees && this.props.employees.length == 0) {
this.props.listEmployees();
}
}
因此,按组件分类,此刻不返回任何员工。有谁知道做到这一点的最佳方法。
class ShareForUsers extends Component {
constructor(props){
super(props);
this.state = {
props,
menuOpen: false,
value: "",
values: []
};
}
componentDidMount() {
if (!!this.props.employees && this.props.employees.length == 0) {
this.props.listEmployees();
}
}
componentWillReceiveProps(nextProps) {
this.setState({ ...nextProps })
}
render() {
if (!!this.state.employees) return <p>no employees</p>;
console.log(this.state.employees)
return (
<div>
{persons}
{this.renderUsers}
<TextField
fullWidth
value={this.state.value}
InputProps={{
startAdornment: this.state.values
.concat()
.sort(({ label: aLabel }, { label: bLabel }) => {
if (aLabel < bLabel) return -1;
else if (aLabel > bLabel) return 1;
return 0;
})
.map(chip => (
<InputAdornment
component={Chip}
label={chip.label}
onDelete={() => {
const value = chip;
this.setState(({ values: prevValues }) => {
const values = prevValues;
const idx = values.indexOf(value);
if (idx === -1) {
values.push(value);
} else {
values.splice(idx, 1);
}
return {
values
};
});
}}
/>
))
}}
onChange={evt => {
const value = evt.target.value;
this.setState({
value,
menuOpen: value.length > 0
});
}}
onFocus={() =>
this.setState(({ value }) => ({
menuOpen: value.length > 0
}))
}
onBlur={() => this.setState({})}
/>
<div>
{this.state.menuOpen ? (
<Paper
style={{
position: "absolute",
zIndex: 100,
width: "100%"
}}
>
{this.state.employees
.filter(
employee =>
employee.user.email.toLowerCase().indexOf(this.state.value) > -1
)
.map(employee => (
<MenuItem
key={employee.value}
onClick={() => {
this.setState(({ values: prevValues }) => {
const values = prevValues.concat();
const idx = values.indexOf(employee);
if (idx === -1) {
values.push(employee);
} else {
values.splice(idx, 1);
}
return {
values,
value: "",
menuOpen: false
};
});
}}
>
{employee.label}
</MenuItem>
))}
</Paper>
) : (
""
)}
</div>
</div>
)
}
}
const shareForUsers = withStyles(styles)(ShareForUsers)
export default connect(
state => state.user,
dispatch => bindActionCreators(actionCreators, dispatch)
)(shareForUsers);
答案 0 :(得分:1)
您不需要将employees
保持在您的状态。您仍然可以在渲染方法中使用this.props.employees
。
请特别注意componentWillReceiveProps
生命周期方法,该方法已标记为在以后的React版本中删除。它在React社区中启用了许多反模式,因此它们提供了替换生命周期getDerivedStateFromProps
。我强烈建议您阅读此生命周期方法中的official blog post。
关于代码的一些说明:
constructor(props){
super(props);
this.state = {
props,
menuOpen: false,
value: "",
values: []
};
}
注释1:
您正在将“道具”置于您的状态。 绝对没有必要。无论何时需要访问状态,您都将可以访问道具。因此,将其置于您的状态中并没有好处,因为不相关的支持正在变化,因此可能会导致不必要的/意外的状态变化。
注意2:
错误的初始状态。如果您确实需要(出于某种原因),请在您的州拥有employees
。然后,您必须在构造函数中正确初始化它们。
注释3:
您缺少用户正在“加载/获取”数据的反馈。到目前为止,当您进行渲染时,首先用户将看到:找不到雇员,然后在获取数据后,他们将神奇地看到屏幕。
如果您的流程本质上是“同步”的,那可能没问题,但是您的行为是异步的,因此您还必须准备遵循组件的状态:
正在加载|错误|已加载(无数据)|已加载(已找到数据)