Home > Enterprise >  React auto add/remove fields based on useState. HTML does not reflect the state change
React auto add/remove fields based on useState. HTML does not reflect the state change

Time:08-28

I am using useState to create an array of objects that later are used to return form fields. User should be able to click on a button and remove a form field based on index. For that I am using spread operator to get a shallow copy of the array, splice delete array item and update form fields through useState.

The problem is that when you click on delete button only last field is removed without regards of the index. Consoling array storing info for the form fields shows that it is updated properly but html is not reflecting the change.

code fragment:

const SearchPage = () => {
  let [loading, setLoading] = useState(false)
  const [results, setResults] = useState()
  const [errorMsg, setErrorMsg] = useState()
  const [formFields, setFormFields] = useState([
    { url: ''}
  ])


  const handleFormChange = (event, index) => {
    let data = [...formFields];
    data[index][event.target.name] = event.target.value;
    setFormFields(data);
  }


  const addFields = () => {
    let object = {
      url: '',
    }
    console.log('Before:',formFields)
    setFormFields([...formFields, object])
  }

  const removeFields = (index) => {
    let data = [...formFields];
    
    data.splice(index, 1)
    console.log(data)
    setFormFields(data)
  }

  return (
            <Box  noValidate autoComplete="off" >
                

              <div className='search' > 
                  <form onSubmit={onSubmit}>
                  {formFields.map((form, index) => {
                    console.log(form)

                    return (
                      <div key={index} style={{width: '95%'}}>
                        <TextField id="outlined-basic"
                          name='url'
                          onChange={event => handleFormChange(event, index)}
                          value={form.name}
                        />
                        <IconButton onClick={() => removeFields(index)}><DeleteIcon /></IconButton>
                      </div>
                    )
                  })}
                </form>
                <IconButton onClick={addFields}> <AddCircleOutlineOutlinedIcon /> </IconButton>
                <br />
              </div>
              </Box>

)

CodePudding user response:

The reason is for the key prop you are setting for each Textfield. it has to be unique for each item.

  const addFields = () => {
    let object = {
      key: Math.random(),
      url: '',
    }
    setFormFields([...formFields, object])
  }
 <div key={form.key} style={{width: '95%'}}>

CodePudding user response:

The problem is you are assigning value form.name to textfield value which does not exist..

                  <TextField id="outlined-basic"
                          name='url'
                          onChange={event => handleFormChange(event, index)}
                          // form.url will fix your issue
                          value={form.url}
                        />
  • Related