简体   繁体   中英

Add/remove form inputs dynamically

I have a form with one initial empty input field that I want to clone using a Add button and to remove with a Remove one.

As it's not recommended to use index for the keys with dynamic forms, I tried to use uniqid module. But each time the state is updating, keys are renewed and I don't have unique data to identify each input of the form. I can add some items, but can't remove.

input fields have no unique values, no id , how can I do ?

const Form = () => {
  const update = e => {};
  const items = [{ content: "", color: "" }];

  return (
    <Fragment>
      {items.map((item, idx) => (
        <input
          htmlFor={`item_${idx}`}
          value={item.content}
          onChange={update("item", idx)}
        />
      ))}
      <button onClick={e => dispatch(add(idx))}>Add</button>
      <button onClick={e => dispatch(remove(idx))}>Remove</button>
    </Fragment>
  );

You may simply extend your existing items to have unique id property - at its very simplest, you may assign the value of maximum used id increased by 1 to that property - I guess, it'll do the trick for most of practical use cases:

const [inputs, setInputs] = useState([{id:0,value:''}]),
      onRowAdd = () => {
          const maxId = Math.max(...inputs.map(({id}) => id))
          setInputs([...inputs, {id:maxId+1, value:''}])
      }

With that, you'll have unique id to anchor to as you delete rows:

onRowRemove = idToDelete => setInputs(inputs.filter(({id}) => id != idToDelete))

Following is the demo of this concept:

 const { useState } = React, { render } = ReactDOM const Form = () => { const [inputs, setInputs] = useState([{id:0,value:''}]), onInput = (id,value) => { const inputsCopy = [...inputs], itemToModify = inputsCopy.find(item => item.id == id) itemToModify.value = value setInputs(inputsCopy) }, onRowAdd = () => { const maxId = Math.max(...inputs.map(({id}) => id)) setInputs([...inputs, {id:maxId+1, value:''}]) }, onRowRemove = idToDelete => setInputs(inputs.filter(({id}) => id != idToDelete)), onFormSubmit = e => (e.preventDefault(), console.log(inputs)) return ( <form onSubmit={onFormSubmit} > { inputs.map(({id,value}) => ( <div key={id}> <input onKeyUp={({target:{value}}) => onInput(id,value)} /> <input type="button" onClick={onRowAdd} value="Add" /> <input type="button" onClick={() => onRowRemove(id)} value="Remove" /> </div> )) } <input type="submit" value="Log Form Data" /> </form> ) } render ( <Form />, document.getElementById('root') )
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

You should create a variable that starts from 0 and adds 1 every time you add a button. That way you will keep track of everyone. Here's an example

let i = 0
const add () => {
//your function to add
i++
//remember i will be the id now
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM