我正在使用Redux构建React中的Web应用程序。这是简单的设备管理器。我正在使用相同的组件在数据库中添加和更新设备。我不确定我的方法是否正确。在这里,您可以找到我的解决方案的一部分:
更新模式:
在componentDidMount中,我正在检查是否以url(编辑模式)传递了deviceId。如果是这样,我正在调用redux动作以从数据库中检索数据。我正在使用connect函数,所以当响应到达时,它将被映射到组件props。
这是我的mapStateToProps(可能我应该只映射特定的属性,但是在这种情况下没关系)
const mapStateToProps = state => ({
...state
})
和componentDidMount:
componentDidMount() {
const deviceId = this.props.match.params.deviceId;
if (deviceId) {
this.props.getDevice(deviceId);
this.setState({ editMode: true });
}
}
接下来,将触发componentWillReceiveProps,我将能够调用setState以便在表单中填充输入。
componentWillReceiveProps(nextProps) {
if (nextProps.devices.item) {
this.setState({
id: nextProps.devices.item.id,
name: nextProps.devices.item.name,
description: nextProps.devices.item.description
});
}
}
添加模式:
添加模式甚至更简单-我只是在每次输入更改时调用setState。
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
这就是我的输入的样子:
<TextField
onChange={this.handleChange('description')}
label="Description"
className={classes.textField}
value={this.state.description}
/>
我不喜欢这种方法,因为我必须在从后端接收数据后调用setState()。我也在使用componentWillReceiveProps,这是一种不好的做法。
有没有更好的方法?例如,我只能使用redux存储而不是组件状态(但是我不需要redux存储中的输入数据)。也许我可以使用React ref字段并摆脱组件状态?
其他问题-我真的应该在每个onChange输入上调用setState吗?
答案 0 :(得分:0)
为避免使用componentWillReceiveProps
,并且由于您正在使用redux,可以执行以下操作:
class YourComponent extends React.Component {
state = {
// ...
description: undefined,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.description === undefined && nextProps.description) {
return { description: nextProps.description };
}
return null;
}
componentDidMount() {
const deviceId = this.props.match.params.deviceId;
if (deviceId) {
this.props.getDevice(deviceId);
this.setState({ editMode: true });
}
}
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
// ...
render() {
let { description } = this.state;
description = description || ''; // use this value in your `TextField`.
// ...
return (
<TextField
onChange={this.handleChange('description')}
label="Description"
className={classes.textField}
value={description}
/>
);
}
}
const mapStateToProps = (state) => {
let props = { ...state };
const { devices } = state;
if (devices && devices.item) {
props = {
...props,
id: devices.item.id,
name: devices.item.name,
description: devices.item.description,
};
}
return props;
};
export default connect(
mapStateToProps,
)(YourComponent);
然后您可以访问id
而不是name
的{{1}},description
和this.props
。之所以起作用,是因为每次您更新Redux存储都会评估this.state
。另外,您将能够通过mapStateToProps
访问description
,并保持this.state
不变。您可以了解有关TextField
here的更多信息。
关于第二个问题,每次输入更改时都调用getDerivedStateFromProps
完全可以;这就是所谓的受控组件,React团队(也不是我)鼓励使用它。参见here。