我正在创建一个允许用户创建评估的应用程序(其他用户可以完成)。现在我正在开发一个“编辑”页面,用户可以在其中加载预填充相关数据的表单 - 但他可以更改这些值。
然而,我遇到了两件事(我怀疑是相关的)。 首先:输入字段不会显示从组件状态派生的默认值。
第二:如果我直接从道具设置输入字段,我将无法再更改值。
组件传递一个名为block_data
的道具,它是一个包含键/键对字符串的dict。
我正在尝试将其加载到像这样的状态
constructor(props) {
super(props);
this.state = {
block: this.props.block_data,
question_list: [],
question_options: ['BO', 'SC', 'SR', 'NO'],
block_list: [],
};
(..)
}
然而,这不起作用。当我签入chrome react扩展时,状态未设置。
输入字段与我在下面包含的示例非常相似。在这里,我从道具中设定了它的价值。在这种情况下,它确实显示正确的初始数据。但是我无法编辑它。
<input
onChange={e => this.changeIsANaturalPartOfLife(e)}
value={this.props.block_data.title}
name="title"
/>
以下是'on change'功能。当我检查chrome react工具时,我可以看到当我开始输入时只更新状态的第一个字母。输入字段不显示任何更改。
changeIsANaturalPartOfLife(e, optional) {
const target = e.target;
const name = target.name;
const value = target.value;
console.log(value);
this.setState({ block: {[name]: value }});
}
我真的不知道该做什么。我在这里想做的事情似乎很简单,但我无法超越这个有缺陷的阶段。有谁知道我做错了什么?
答案 0 :(得分:3)
正如您在评论中提到的那样:“数据是从DjangoRestAPI加载的。”
第一个问题的解决方案:
您需要使用componentwillreceiveprops
生命周期方法来使用新的道具值更新状态(从服务器成功获取后),否则子组件的状态将始终具有父组件的初始数据。
根据 DOC :
在安装的组件之前调用componentWillReceiveProps() 收到新的道具。如果您需要更新状态以响应 prop更改(例如,重置它),您可以比较this.props 和nextProps并使用this.setState()执行状态转换 这种方法。
使用此方法:
componentwillreceiveprops(nextProps) {
// compare nextProps.block_data and this.state.block if not equal
this.setState({
block: nextProps.block_data
})
}
解决第二个问题:
当你直接使用道具而不是存储到状态时,你需要在onChange期间更新父组件中的值,因为你正在使用this.props.value
并更新this.state.value
,因此{{ 1}}将始终相同,并且不允许您键入任何内容。