【问题标题】:Add multiple input field dynamically in react在反应中动态添加多个输入字段
【发布时间】:2022-01-21 08:56:28
【问题描述】:

我有一个包含三个输入元素和一个删除按钮的 div。需要的是,当用户单击添加按钮时,它将动态添加此 div,当用户单击删除按钮时,它将删除此 div。我可以使用以下方法动态添加一个输入元素(没有 div 容器)。

  • 在状态变量中创建一个数组。
  • 借助数组索引(如 name0、name1)为动态输入字段分配名称

如何处理这么多输入字段?当我将整个 div 创建为单独的组件时,问题会进一步扩大。我正在使用基于类的组件。

handleChange=(event) =>
  {
    this.setState({[event.target.name]:event.target.values});
  }

render()
  {
    return(
      <div className="row">
        <button type="button" onClick={this.addElement}>Add</button>
        <div className="col-md-12 form-group">
          <input type="text" className="form-control" name="name" value={this.state.name} onChange={this.handleChange} />
          <input type="text" className="form-control" name="email" value={this.state.email} onChange={this.handleChange} />
          <input type="text" className="form-control" name="phone" value={this.state.phone} onChange={this.state.phone} />
          <button type="button" onClick={this.removeElement}>Remove</button>
        </div> 
      </div>
    )
  }

【问题讨论】:

  • 您是要添加/删除div,还是添加/删除输入?你质疑这两种情况之间的跳跃。如果是输入,在添加之前如何确定输入的 type 是什么?
  • 这可能对你有帮助:bapunawarsaddam.medium.com/…
  • @Andy 我正在尝试添加一个包含输入的 div。输入类型是静态的,不会改变。
  • @Pranaykumar 您可以使用数组/对象并将其映射以返回所需的组件。并使用状态推送到数组,它将为您呈现组件

标签: javascript html reactjs


【解决方案1】:

我会从配置的角度来解决这个问题,因为它更具可扩展性。如果你想最终改用 Formik 或 React Form 之类的东西,它会让移动变得更容易一些。

有一个要转换为输入字段的对象数组。您的主组件应保持状态是否显示 &lt;Form /&gt; 组件,以及是否在配置和任何相关处理程序中可见。

您的表单组件应维护输入的状态,并在您提交时将完成状态传递给父级。

const { Component } = React;

class Example extends Component {

  constructor(props) {
    super();

    // The only state in the main component
    // is whether the form is visible or not
    this.state = { visible: false };
  }

  addForm = () => {
    this.setState({ visible: true });
  }

  removeForm = () => {
    this.setState({ visible: false });
  }

  handleSubmit = (form) => {
    console.log(form);
  }

  render() {
    
    const { visible } = this.state;
    const { config } = this.props;
    
    return (

      <div>
        <button
          type="button"
          onClick={this.addForm}
        >Add form
        </button>

        {visible && (
          <Form
            config={config}
            handleSubmit={this.handleSubmit}
            handleClose={this.removeForm}
          />
        )}

      </div>
    );
  
  }

};

class Form extends Component {

  constructor(props) {
    super();
    this.state = props.config.reduce((acc, c) => {
      return { ...acc, [c.name]: '' };
    }, {});
  }

  handleChange = (e) => {
    const { name, value } = e.target;
    this.setState({ [name]: value });
  }

  handleSubmit = () => {
    this.props.handleSubmit(this.state);
  }

  render() {

    const { name, email, phone } = this.state;
    const { handleClose, config } = this.props;
        
    return (
      
      <div onChange={this.handleChange}>
        
        {config.map(input => {
          const { id, name, type, required } = input;
          return (
            <div>
              <label>{name}</label>
              <input key={id} name={name} type={type} required={required} />
            </div>
          )
        })}
        
        <button type="button" onClick={this.handleSubmit}>Submit form</button>
        
        <button type="button" onClick={handleClose}>Remove form</button>
      
      </div>
    
    );
  
  }

}

const config = [
  { id: 1, name: 'name', type: 'text', required: true },
  { id: 2, name: 'email', type: 'email', required: true },
  { id: 3, name: 'phone', type: 'phone', required: true }
];


ReactDOM.render(
  <Example config={config} />,
  document.getElementById('react')
);
input { display: block; }
label { text-transform: capitalize; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

【讨论】:

    【解决方案2】:

    写下如何生成你想要的东西的每一个细节有点困难。所以我发现准备一个stackblitz 链接让你看看它是如何做到的要容易得多,并且链接在下面准备好了:

    generating a dynamic div adding and removing by handling inputs state value

    【讨论】:

      【解决方案3】:

      我希望这对您的问题有所帮助。 我制作了一个包含三个输入标签的子组件。

      // parent component
      import React, { Component } from "react";
      import TextField from "./TextField";
      
      class App extends Component {
        constructor(props) {
          super(props);
          this.state = {
            users: [
              {
                key: Date.now(),
                name: "",
                email: "",
                phone: ""
              }
            ]
          };
        }
      
        onChange = (inputUser) => {
          this.setState((prevState) => {
            const newUsers = prevState.users.map((element) => {
              if (element.key === inputUser.key) return inputUser;
              return element;
            });
            return { users: newUsers };
          });
        };
      
        addElement = () => {
          const { name, email, phone } = this.state;
          this.setState((prevState) => ({
            users: prevState.users.concat({
              key: Date.now(),
              name,
              email,
              phone
            })
          }));
        };
      
        removeElement = (id) => {
          this.setState((prevState) => ({
            users: prevState.users.filter((user) => user.key !== id)
          }));
        };
      
        render() {
          const { users } = this.state;
          return (
            <div className="row">
              <button type="button" onClick={this.addElement}>
                Add
              </button>
              <div className="col-md-12 form-group">
                {users.map((user) => (
                  <React.Fragment key={user.key}>
                    <TextField
                      value={user}
                      onChange={(inputUser) => this.onChange(inputUser)}
                    />
                    <button
                      type="button"
                      onClick={() => this.removeElement(user.key)}
                      disabled={users.length <= 1}
                    >
                      Remove
                    </button>
                  </React.Fragment>
                ))}
              </div>
            </div>
          );
        }
      }
      
      export default App;
      
      
      
      // child component
      import { Component } from "react";
      
      class TextField extends Component {
        handleChange = (ev) => {
          const { name, value } = ev.target;
          this.props.onChange({
            ...this.props.value,
            [name]: value
          });
        };
      
        render() {
          const { value: user } = this.props;
          return (
            <>
              <input
                className="form-control"
                name="name"
                value={user.name}
                onChange={this.handleChange}
                placeholder="name"
                type="text"
              />
              <input
                className="form-control"
                name="email"
                value={user.email}
                onChange={this.handleChange}
                placeholder="email"
                type="text"
              />
              <input
                className="form-control"
                name="phone"
                value={user.phone}
                onChange={this.handleChange}
                placeholder="phone"
                type="text"
              />
            </>
          );
        }
      }
      
      export default TextField;
      
      

      您也可以在下面的代码框链接中查看代码。 https://codesandbox.io/s/suspicious-heisenberg-xzchm

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-23
        • 2014-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多