首先,这是一个简化示例:Codepen Project
我正在反应中构建一个编辑表单,它会检查是否有任何更改。 如果有任何更改,您只能保存表单,并且通过更改匹配的输入元素上的样式(border-left)将显示您所做的任何更改。 It looks like this
为此,我将组件状态中的原始数据/状态保存在componentDidMount方法中,并将其与不同输入的状态进行比较。
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
}
在每次输入更改时,将输入值与initialState进行比较:
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),这意味着我无法在我的标签列表中获取更改。 /强> 但是,如果我正在创建向新项目添加标记而不是编辑现有项目,它确实有效... 我不知道如何解决这个问题,因为我真的不知道是什么导致它,我会喜欢一些帮助。
感谢您阅读本文:)
答案 0 :(得分:1)
不要将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可能会修改tags
数组。如果您保留副本,则不会修改该副本。