Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript react表单中的意外状态更新_Javascript_Forms_Reactjs - Fatal编程技术网

Javascript react表单中的意外状态更新

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

首先,这是一个简化的示例:

我正在react中构建一个编辑表单,检查是否有任何更改。 只有在有任何更改的情况下才能保存表单,并且所做的任何更改都将通过更改匹配输入元素上的样式(左边框)来显示

为此,我在componentDidMount方法的component状态中保存原始数据/状态,并将其与不同输入的状态进行比较

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检查了一下便条。