【问题标题】:How to set a general onchange for the dynamic form fields coming from api in react js.?如何在 react js 中为来自 api 的动态表单字段设置一个通用的 onchange?
【发布时间】:2020-12-24 08:10:10
【问题描述】:

我正在使用 react 中的表单。

我面临的挑战是,每当我为输入字段设置 onchange 处理程序时,它都会更改我拥有的所有输入字段的值。

表单输入字段已映射并来自 api。我想要的是一个通用的更改处理程序来管理所有输入字段。

import React, { Component } from "react";
import {
  TextInputComponent,
  RadioInputComponent,
  SelectComponent,
} from "../../components/index";
import IntlMessages from "../../common/constants/IntlMessages";

class DummyForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      field: "",
      checkBox: "",
      options: "",
      radioField: "",
      error: "",
    };
  }
  componentDidMount() {
    const code = window.location.pathname.split("/")[2];
    this.props.getEmsForms(code);
  }

//this my on change handler and it would be great help if someone can tell where iam wrong.
  handleChange(e) {
    this.setState({
      [e.target.name]: e.target.value,
    }) 
  }

  submit = () => {
    const { field, checkBox, options, radioField } = this.state;
    const auth = this.props.user.data.user.access_token;
    this.props.updateEmailPhone({
      email,
      address,
      auth,
    });
  };

  render() {
    return (
      <React.Fragment>
        <div className="row justify-content-center py-2 my-2">
          <div className="col-sm-12 col-lg-5 col-md- border border-info bg-light">
            <div className="row p-3">
              {this.props.getForms.data
                ? this.props.getForms.data.map((item) => {
                    return (
                      <div className="col-12 p-2">
                        {item.inputType == "textbox" ? (
                          <TextInputComponent
                            key={item.fieldName}
                            label={item.fieldLabelText}
                            type="text"
                            placeholder={item.fieldName}
                            value={this.state.field}
                            onChange={(e) =>
                              this.handleChange(e, "field")
                            }
                          />
                        ) : item.inputType == "dropdown" ? (
                          <>
                            <label>{item.fieldLabelText}</label>
                            <select
                              className="custom-select "
                              id="inputGroupSelect01"
                              onChange={(e) =>
                                this.handleChange({ options: e.target.value })
                              }
                            >
                              {item.inputOptions.map((key) => (
                                <option>{key.value}</option>
                              ))}
                            </select>
                          </>
                        ) : item.inputType == "checkbox" ? (
                          <SelectComponent
                            name={"select2"}
                            value={this.state.checkBox}
                            label={item.fieldLabelText}
                            onChange={(e) =>
                              this.setState({ checkBox: e.target.value })
                            }
                          />
                        ) : item.inputType == "radio" ? (
                          <RadioInputComponent
                            title="gender"
                            value={this.state.gender}
                            name={item.fieldLabelText}
                            onChange={(e) => {
                              this.setState({ radioField: e.target.value });
                            }}
                          />
                        ) : null}
                      </div>
                    );
                  })
                : this.props.getForms.messages}

              <div className="row" style={{ marginTop: "50px" }}>
                {/* <div className="col d-flex justify-content-start">
              <button className="btn-danger" onClick={this.toggleModal}>
              Ja
              </button>
            </div> */}
                {this.props.getForms.data && (
                  <div className="col d-flex justify-content-end">
                    <button className="btn btn-success button-margin">
                      <IntlMessages id="blank.button" />
                    </button>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

export default DummyForm;

【问题讨论】:

  • 是的,它给出了在状态中声明的字段对象

标签: javascript reactjs forms api


【解决方案1】:

您可以从事件目标中获取namevaluetypechecked 属性,并使用类似形状的这些属性设置状态

{
  "input": "a",
  "select": "2",
  "radio": "3",
  "checkbox1": true,
  "checkbox3": true,
  "checkbox2": true
}
import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [state, setState] = useState({});

  const onChange = (e) => {
    const { name, value, checked, type } = e.target;
    const newVal = type === "checkbox" ? checked : value;

    setState({
      ...state,
      [name]: newVal
    });
  };

  return (
    <>
      <div className="section">
        <label>
          Input
          <input name="input" onChange={onChange} />
        </label>
      </div>
      <div className="section">
        <label>
          select
          <select name="select" onChange={onChange}>
            <option>1</option>
            <option>2</option>
            <option>3</option>
          </select>
        </label>
      </div>
      <div className="section">
        <fieldset>
          <legend>Radio</legend>
          <label>
            <input type="radio" name="radio" value="1" onChange={onChange} />1
          </label>

          <label>
            <input type="radio" name="radio" value="2" onChange={onChange} />2
          </label>

          <label>
            <input type="radio" name="radio" value="3" onChange={onChange} />3
          </label>
        </fieldset>

        <fieldset>
          <legend>Checkbox</legend>
          <label>
            <input type="checkbox" name="checkbox1" onChange={onChange} />1
          </label>

          <label>
            <input type="checkbox" name="checkbox2" onChange={onChange} />2
          </label>

          <label>
            <input type="checkbox" name="checkbox3" onChange={onChange} />3
          </label>
        </fieldset>

        <pre>{JSON.stringify(state, null, 2)}</pre>
      </div>
    </>
  );
}

【讨论】:

    【解决方案2】:

    我认为这应该可行:

    handleChange(e,prop) {
        this.setState({
        ...this,
          [prop]: e.target.value,
        }) 
      }
    

    现在当你调用 handleChange 传递道具时,例如你正在为 radioField 调用 handleChange :

    <RadioInputComponent
                                title="gender"
                                value={this.state.gender}
                                name={item.fieldLabelText}
                                onChange={(e) => {
                                  handleSubmit(e,"radioField"});
                                }}
                              />
    

    【讨论】:

    • 它没有用我这样调用我的 onchange onChange={(e) =&gt; this.handleChange(e, "field") }
    • 你试过吗。 e.target.name 的 console.log 以查看它是否持有什么值?
    • 是的,它给出了在状态中声明的字段对象
    【解决方案3】:
    // In parent
    
    <child inputNames={this.props.getForms.data.map(item)=>item.fieldName } />
    
    //In child
    
    constructor =(props)=>{
      super(props)
      this.inputNames = {}
      this.props.inputNames.forEach(elem=> this.inputNames[elem]="")
      
      //Here put the state for your component
      this.myState = {
        Other component states goes here...
      }
      
      //Combine states
      this.state = Object.assign(this.inputNames, this.myState)
    }
    
    handleChange = (e) => {
      this.setState({
        [e.target.name]: e.target.value
      })
      
      
    //In return (for any given input field)
    this.props.inputNames.map(elem=>(
      <input 
      key= {your key...}
      name={elem.fieldName}
      value={this.state.fieldName}
      onChange = {this.handleChange}
      />
    ))
       
       
       
       
       
       
       
       
    
    • 在父组件中获取输入字段
    • 将一组输入字段从父组件作为名为 inputNames 的道具传递给子组件
    • 构造一个包含所有输入字段名称的对象,并在代码中用空字符串'this.inputNames'初始化状态
    • 在映射到输入字段时,使输入字段的名称与上述过程中'this.inputNames'中的格式相同

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 2021-02-02
      • 2021-06-06
      • 2021-07-13
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多