React - 在setState中更改JSON对象

6

我有一个表格,其中包含三个字段,handleChange 方法可以在第一个字段(DateOfBirth)中工作,但不能在(Id1)和(Id2)字段中工作。

某些原因导致 setState 在尝试更改(Id1||Id2)字段的值时返回以下错误信息:

"一个组件将类型为文本的受控输入变成了不受控制的。输入元素不应该从受控制的转换成不受控制的(反之亦然)。在组件的生命周期内决定使用受控制的还是不受控制的输入元素"

import React, { Component } from 'react';

class Form extends React.Component {

    constructor(props){
        super(props);
        this.state = { DateOfBirth:'1990-01-24', Metadata: {Id1:'33813518109', Id2:'John Doe'}}
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) { 
        const target = event.target;
        const name = target.name;        
        var value = target.value;         

        if(name === "Id1" || name === "Id2")            
            this.setState({Metadata:{[name]: value}});     
        else
            this.setState({[name]: value});
    }  

    render() { 
        return (             
            <div>
                <form onSubmit={this.handleSubmit}>                                          
                    <input name="DateOfBirth" type="date" onChange={this.handleChange} value={this.state.DateOfBirth} />                                           
                    <input name="Id1" type="text" onChange={this.handleChange} value={this.state.Metadata.Id1} />   
                    <input name="Id2" type="text" onChange={this.handleChange} value={this.state.Metadata.Id2} />
                </form>
            </div>            
        );
    }
}

export default Form;

可能是重复的问题,参考 this.setState isn't merging states as I would expect - Giorgi Moniava
1个回答

11

来自React文档。

更新器的输出将与prevState浅合并。

这意味着当你执行

// name === 'Id1'
// value === 'dummy'
this.setState({Metadata:{[name]: value}});

那么状态中的Metadata键将具有以下结构:

{
  Metadata: {
    Id1: "dummy"
  }
}

你看到问题了吗?现在输入框 Id2 接收到的值是undefinedthis.state.Metadata.Id2 不存在),这将导致 React 抛出有关不受控制组件的错误。

要解决这个问题,你需要完全复制嵌套对象属性:

this.setState(prevState => ({
  Metadata:{
    ...prevState.Metadata,
    [name]: value
  }
}));

1
我理解了,非常感谢。 - user2546477

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接