代码之家  ›  专栏  ›  技术社区  ›  jgoraya

更新JSON状态对象问题

  •  0
  • jgoraya  · 技术社区  · 6 年前

    我很难更新我的JSON状态对象。我的应用程序背后的基本前提是,我有一个嵌入了子组件的父组件。基于某些用户交互,子组件将以编辑模式加载,允许用户更改表单中的字段(否则为只读)。

    基于子组件窗体中的更改,更改将成功地传递回函数的父级(onOverviewChange)。fieldName和fieldValue似乎被正确地传回,但是我似乎无法用新值更新状态。

    对如何解决这个问题有什么想法吗?

    export default class Patient extends React.Component {
     constructor(props) {
       super(props);
       autoBind(this);
       ...
       this.onOverviewChange = this.onOverviewChange.bind(this);
     }
    
    onOverviewChange(event) {
        const fieldName = event.target.name;
        const fieldValue = event.target.value;
        const fieldID = event.target.id;
        /* Approach # 1: This way updates states but doesn't allow me to change the text box*/
             this.setState((prevState) => {
                let patient = [...prevState.PATIENT];
                patient[0] = {...patient[0], [fieldName]: fieldValue};
                console.log("JSON:" + JSON.stringify(patient[0]));
                return({patient});
              });
    
        /* Approach # 2:  this way updates the text box but not the state
        let patient = [...this.state.PATIENT];
        console.log("Target Name:" + fieldName +". Value:" + fieldValue + " ID: " + fieldID + ". JSON:" + JSON.stringify(patient));
        patient[0] = {...patient[0], [fieldName]: fieldValue};
        this.setState({PATIENT: patient}); */
      }
    
    render() {
    ...
      <OverviewWrapper onchange={this.onOverviewChange} overview={this.state.PATIENT} ovtype={this.state.COMPPROPS} />
    ...
    }
    

     export default class OverviewWrapper extends React.Component {
    
    constructor(props) {
        super(props);
        autoBind(this);
      }
    
    render() {
    
        const overview = this.props.overview;
        const type = this.props.compState;
    
        let OverviewWrapper = null
        switch (type) {
            case "Edit" : 
                OverviewWrapper = OverviewEditPane
                break
            default: 
                OverviewWrapper = OverviewPane
                break
        }
    
        return <OverviewWrapper {...this.props}  />
    }
    }
    

    然后我有了可编辑的子组件,用户可以在其中更改值

    export default class OverviewEditPane extends React.Component {  
    
    constructor(props) {
      super(props);
      autoBind(this);
    
    }
    
    render () {
      return (
              <table>
                <FormFields>
                    <tr>
                      <td>{this.props.overview.map((P) => {return <TextInput size='small'  key={P.id} id={P.id} value={P.FName} onChange={P.onOverviewChange}  />;})}</td>
                      **<!--OTHER FIELDS LISTED HERE --->**
                    </tr>
    

    "PATIENT": [{
        "id": 6,
        "FName": "Chris",
        "LName": "Baker",
        "Height": "62",
        "Weight": 320,
        "DOB": "1988-09-18T00:00:00",
        "Active": true
      }]
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   keul    6 年前

    记得吗 setState 签名。看到了吗 https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

    所以:

    onOverviewChange(event) {
        const fieldName = event.target.name;
        const fieldValue = event.target.value;
        const fieldID = event.target.id;
        this.setState((oldState) => {
            let patient = [...oldState.PATIENT];
            console.log("Target Name:" + fieldName +". Value:" + fieldValue + " ID: " + fieldID + ". JSON:" + JSON.stringify(patient));
            patient[0] = {...patient[0], [fieldName]: fieldValue};
            return({ patient });
        });
    }
    
        2
  •  0
  •   Dyo    6 年前

    关键字、变量、函数名和任何其他标识符必须 务必用大写字母输入

    执行此操作时,需要保持状态属性名称的一致性:

    this.setState({patient});
    

    你的州变成:

    {
      PATIENT: [{"id": 6, ......}],
      patient: [{"id": 6, ......, updatedField: value}]
    }
    

    我建议你用不大写的名字(“病人”)来初始化你的状态,并且只使用这个名字。

    constructor(props) {
      super(props);
      this.state = {
        patient: PATIENT
      }
    }