Javascript react表单中的意外状态更新
首先,这是一个简化的示例: 我正在react中构建一个编辑表单,检查是否有任何更改。 只有在有任何更改的情况下才能保存表单,并且所做的任何更改都将通过更改匹配输入元素上的样式(左边框)来显示 为此,我在componentDidMount方法的component状态中保存原始数据/状态,并将其与不同输入的状态进行比较Javascript react表单中的意外状态更新,javascript,forms,reactjs,Javascript,Forms,Reactjs,首先,这是一个简化的示例: 我正在react中构建一个编辑表单,检查是否有任何更改。 只有在有任何更改的情况下才能保存表单,并且所做的任何更改都将通过更改匹配输入元素上的样式(左边框)来显示 为此,我在componentDidMount方法的component状态中保存原始数据/状态,并将其与不同输入的状态进行比较 componentDidMount() { // if the project is accessed from home and is not a new project, pr
componentDidMount() {
// if the project is accessed from home and is not a new project, project data will be passed along
if (this.props.project) {
this.setState({
name: this.props.project.name,
tags: this.props.project.tags
}, this.setInitialState)
} else if (this.props.edit && this.props.match.params.id) {
// instead of an api call to get project data, if the project is accessed directly by url
const project = projects.find((project) => project.name === this.props.match.params.id)
this.setState({
name: project.name,
tags: project.tags
}, this.setInitialState)
}
// if there are no project data or an edit prop, it's a new project and the initialState remains empty
}
在每次输入更改时,将输入值与初始状态进行比较:
compareInputData() {
const formFields = {
name: {
ref : this.name,
changed : false
},
tags: {
ref : this.tagList,
changed : false
}
}
const state = this.state
const first = this.state.initialState
const nameHasChanged = state.name !== first.name
const tagsHaveChanged = state.tags.length !== first.tags.length
nameHasChanged
? ( formFields.name.changed = true )
: ( formFields.name.changed = false )
tagsHaveChanged
? ( formFields.tags.changed = true )
: ( formFields.tags.changed = false )
nameHasChanged || tagsHaveChanged
? (this.setState({
isChanged: true
}))
: (this.setState({
isChanged: false
}))
this.handleChangedInputStyles(formFields)
}
如果有更改,则会更改匹配元素的样式:
handleChangedInputStyles(formFields) {
const formFieldKeys = Object.keys(formFields)
formFieldKeys.map(key => {
formFields[key].changed
? formFields[key].ref.style.borderLeft = `2px solid orange`
: formFields[key].ref.style.borderLeft = '1px solid black'
})
}
这是我希望它在普通输入字段上的工作方式,但我也将相关标记保存为数组,以列表的形式显示每当我更新该列表(this.state.tags)时,标记的原始状态也会被更新(this.state.initialState.tags),这意味着我无法获取标记列表中的更改。
但是,如果我正在创建一个新项目中添加标记,而不是编辑一个现有项目,那么它确实可以工作。。。
我不知道如何解决这个问题,因为我真的不知道是什么原因造成的,我希望得到一些帮助
感谢您阅读本文:)请勿将
this.state.initialState
存储在状态中。而是将其存储在成员中。例如:
constructor(props) {
this.initialState = Object.assign({}, whatever...);
this.initialState.tags = [].concat(this.initialState.tags); // Keep a shallow copy of this array.
}
注意:React可以在内部修改
标记
数组。如果您保留了一份副本,该副本将不会被修改。Nice,只要我包含第二行,这实际上是有效的。如果我不这样做,这个.initialState也会被更新。不幸的是,我仍然不明白为什么会发生这种情况,或者为什么第二行正好阻止了这种情况…@YannickPanis检查了一下便条。