1

I have a React functional component with a form, onSubmit I want to loop through all form elements....

export default function TransactionFilter() {

return (
   <form onSubmit={handleSubmit}>
      <TextField id="username" /><br/>
      <TextField id="password" /><br/>
   </form>
)

const handleSubmit = (event) => {
        event.preventDefault();
        var formElements = event.target.elements

        formElements.forEach(element => 
          console.log(`I found this ${element}`)
        );

But this code is giving me an error...

react-dom.development.js:476 Uncaught TypeError: formElements.forEach is not a function
    at handleSubmit (FilterForm.js:49)
    at HTMLUnknownElement.callCallback (react-dom.development.js:337)

Am I not using forEach in the right way? If not, then what is the correct way to iterate over form elements array in React ?

1
  • Usually using react you would avoid the need to iterate over actual elements. You should be binding to the on change of each element to some sort of state object. It should be a rare case that you need access to something other than the values. Commented Feb 25, 2020 at 18:30

3 Answers 3

2

The elements object is actually a HTMLFormControlsCollection object.

You can use the Array.prototype.forEach method to iterate the collection like this:

Array.prototype.forEach.call(event.target.elements, (element) => {
  console.log(element);
})
Sign up to request clarification or add additional context in comments.

Comments

0

event.target.elements will return undefined

I suggest doing it in react way, have an array of all form elements in state.

 export default function TransactionFilter() {
  const [formData, setFormData] = React.useState([
    { id: 'username', value:'' },
    { id: 'password', value:'' }
  ]);
  const handleSubmit = (event) => {
    event.preventDefault();
    formData.forEach(element => 
      console.log(`I found this ${element.value}`)
    );
  };
  return (
       <form onSubmit={handleSubmit}>
          {formData.map((element, index) => {
            return ( <React.Fragment>
                     <TextField id={element.id} value={element.value} 
                     onChange={e => {
                       setFormData(
                         [
                           ...formData.slice(0, index), 
                           { ...formData[index], value: e.target.value },
                           ...formData.slice(index + 1)
                         ]
                       );
                     }}

                     />
                     <br/>
                   </React.Fragment>
            );
          })}
       </form>
  );
}

Comments

0

You can also use the of syntax:

const handleSubmit = event => {
    event.preventDefault()

    for (const element of event.target.elements) {
        console.log(`I found this ${element}`)
    }
}

    
   

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.