更新状态内对象的动态字段

时间:2020-04-26 19:20:30

标签: reactjs

这篇文章与我正在尝试做的非常接近,但是没有涵盖动态字段:Updating an object with setState in React

动态字段的含义:(工作代码)

import React, { Component } from 'react';

class ComponentName extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name: "",
            age: "",
            email: "",
            manager: ""
        }
    }

    handleValueChange = (ev) => {
        this.setState({[ev.target.name]: ev.target.value}); // <----- dynamic field
    }

    handleSubmit = (ev) => {
        ev.preventDefault();
        console.log("Form Values =", this.state);
    }

    render() {
        <form onSubmit={ev => this.handleSubmit(ev)}>
            <div>
                <label>Name:</label>
                <input type="text" name="name" onChange={ev => this.handleValueChange(ev)} value={this.state.name} />
            </div>
            <div>
                <label>Age:</label>
                <input type="text" name="age" onChange={ev => this.handleValueChange(ev)} value={this.state.age} />
            </div>
            <div>
                <label>Age:</label>
                <input type="email" name="email" onChange={ev => this.handleValueChange(ev)} value={this.state.email} />
            </div>
            <div>
                <label>Age:</label>
                <input type="text" name="manager" onChange={ev => this.handleValueChange(ev)} value={this.state.manager} />
            </div>
            <button type="submit">Submit</button>
        </form>
    }
}

export default BadgeContractorRequest;

^请注意,我如何使用this.setState({[ev.target.name]: ev.target.value});来避免对每个字段进行硬编码。


我想做的是...在同一状态下更新多个表单对象:(断码)

import React, { Component } from 'react';

// Components
import FormOne from './formOne.js';
import FormTwo from './formTwo.js';
import FormThree from './formThree.js';

class ComponentName extends Component {
    constructor(props) {
        super(props);
        this.state = {
            formRequestTypeValue: "",
            formOne: {
                name: "",
                age: "",
                requestType: "",
                manager: ""
            },
            formTwo: {
                managerName: "",
                email: "",
                position: ""
            },
            formThree: {
                product: "",
                details: ""
            }
        }
    }

    formRequestTypeOnChangeHandler = (ev) => {
        this.setState({...this.state, formRequestTypeValue: ev.target.value});
    }

    handleValueChange = (ev) => {
        // This is where I'm Lost...
        this.state.formRequestTypeValue === "formOne" && this.setState({...this.state, formOne.[ev.target.name]: ev.target.value});
        this.state.formRequestTypeValue === "formTwo" && this.setState({...this.state, formTwo.[ev.target.name]: ev.target.value});
        this.state.formRequestTypeValue === "formThree" && this.setState({...this.state, formThree.[ev.target.name]: ev.target.value});
    }

    handleSubmit = (ev) => {
        ev.preventDefault();
        console.log("Form Values =", this.state);
    }

    render() {
        <form onSubmit={ev => this.handleSubmit(ev)}>
            <div>
                <select onChange={ev => this.formRequestTypeOnChangeHandler(ev)} value={this.state.formRequestTypeValue}>
                    <option value="">Please Select a Form</option>
                    <option value="formOne">Form One</option>
                    <option value="formTwo">Form Two</option>
                    <option value="formThree">Form Three</option>
                </select>
            </div>
            {
                this.state.formRequestTypeValue === "formOne" && 
                    <div>
                        <FormOne handleValueChange={this.handleValueChange} handleSubmit={this.handleSubmit} formValues={this.state.formOne} />
                    </div>
            }
            {
                this.state.formRequestTypeValue === "formTwo" && 
                    <div>
                        <FormTwo handleValueChange={this.handleValueChange} handleSubmit={this.handleSubmit} formValues={this.state.formTwo} />
                    </div>
            }
            {
                this.state.formRequestTypeValue === "formThree" && 
                    <div>
                        <FormThree handleValueChange={this.handleValueChange} handleSubmit={this.handleSubmit} formValues={this.state.formThree} />
                    </div>
            }
        </form>
    }
}

export default ComponentName;

我之所以没有将<form>分成自己的组成部分,是因为如果用户从下拉菜单中选择其他形式,然后返回到他们自己的表单,我想保持字段值的状态先前的选择。


这是我被困的地方:

handleValueChange = (ev) => {
    // This is where I'm Lost...
    this.state.formRequestTypeValue === "formOne" && this.setState({...this.state, formOne.[ev.target.name]: ev.target.value});
    this.state.formRequestTypeValue === "formTwo" && this.setState({...this.state, formTwo.[ev.target.name]: ev.target.value});
    this.state.formRequestTypeValue === "formThree" && this.setState({...this.state, formThree.[ev.target.name]: ev.target.value});
}

任何人都不知道handleValueChange的语法魔术是什么?


编辑更新:

也尝试了以下方法,但是没有运气:

enter image description here

1 个答案:

答案 0 :(得分:2)

第一:

例如,您不需要在formThree之后加上.。如下所示:

formThree[ev.target.name]

然后,您需要保留过去的formOne字段,以防止其为空。为此,您需要如下代码:

this.state.formRequestTypeValue === "formOne" &&
  this.setState((prevState) => ({
    ...prevState,
    formOne: {
      ...prevState.formOne,
      [ev.target.name]: ev.target.value,
    },
  }));

prevState是您最后一个尚未更改的this.state

使用formOne: {...prevState.formOne,[ev.target.name]: ev.target.value},,您将携带旧的formOne字段,并且将覆盖[ev.target.name]字段。

您还需要为其他形式重复此操作。