349

I have a simple form in my render function, like so:

render : function() {
      return (
        <form>
          <input type="text" name="email" placeholder="Email" />
          <input type="password" name="password" placeholder="Password" />
          <button type="button" onClick={this.handleLogin}>Login</button>
        </form>
      );
    },
handleLogin: function() {
   // How can I access email and password here?
}

What should I write in my handleLogin: function() { ... } to access Email and Password fields?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
myusuf
  • 11,810
  • 11
  • 35
  • 50
  • 20
    Note: you should handle `onSubmit` on the form rather than the button click - this way you will also handle the user submitting the form by pressing enter. – brettwhiteman May 28 '16 at 19:59
  • 13
    A `
    ` with a `
    – Ross Allen May 31 '16 at 16:53
  • 1
    there is also the benefit of browser's native checking on empty values of required fields – Sang Oct 10 '20 at 00:39

31 Answers31

390

There are a few ways to do this:

1) Get values from array of form elements by index

handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target[0].value)
}

2) Using name attribute in html

handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target.elements.username.value) // from elements property
  console.log(event.target.username.value)          // or directly
}

<input type="text" name="username"/>

3) Using refs

handleSubmit = (event) => {
  console.log(this.inputNode.value)
}

<input type="text" name="username" ref={node => (this.inputNode = node)}/>

Full example

class NameForm extends React.Component {
  handleSubmit = (event) => {
    event.preventDefault()
    console.log(event.target[0].value)
    console.log(event.target.elements.username.value)
    console.log(event.target.username.value)
    console.log(this.inputNode.value)
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input
            type="text"
            name="username"
            ref={node => (this.inputNode = node)}
          />
        </label>
        <button type="submit">Submit</button>
      </form>
    )
  }
}
Aliaksandr Sushkevich
  • 11,550
  • 7
  • 37
  • 44
225

Use the change events on the inputs to update the component's state and access it in handleLogin:

handleEmailChange: function(e) {
   this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
   this.setState({password: e.target.value});
},
render : function() {
      return (
        <form>
          <input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
          <input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
          <button type="button" onClick={this.handleLogin}>Login</button>
        </form>);
},
handleLogin: function() {
    console.log("EMail: " + this.state.email);
    console.log("Password: " + this.state.password);
}

Working fiddle.

Also, read the docs, there is a whole section dedicated to form handling: Forms

Previously you could also use React's two-way databinding helper mixin to achieve the same thing, but now it's deprecated in favor of setting the value and change handler (as above):

var ExampleForm = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {email: '', password: ''};
  },
  handleLogin: function() {
    console.log("EMail: " + this.state.email);
    console.log("Password: " + this.state.password);
  },
  render: function() {
    return (
      <form>
        <input type="text" valueLink={this.linkState('email')} />
        <input type="password" valueLink={this.linkState('password')} />
        <button type="button" onClick={this.handleLogin}>Login</button>
      </form>
    );
  }
});

Documentation is here: Two-way Binding Helpers.

Edgar
  • 6,022
  • 8
  • 33
  • 66
jbaiter
  • 6,913
  • 4
  • 30
  • 40
  • What are the pros and cons of going with `onchange` v/s going with mixin ? – myusuf May 02 '14 at 12:55
  • I think it's not really promoted in the docs since React's model of dataflow is more like 'one-way databinding' and users are encouraged to think more in these terms. That being said, the docs themselves acknowledge that ReactLink is purely syntactic sugar for the 'onChange'/'setState' way of doing it. – jbaiter May 02 '14 at 13:06
  • 3
    To correctly mimic the functionality of `valueLink`, your first example should set the `value` of the input elements. Without that, the values are ["uncontrolled"](https://facebook.github.io/react/docs/forms.html#uncontrolled-components) in React terms. ``. – Ross Allen May 02 '14 at 18:41
  • The mixin method gives me the following error: `Uncaught TypeError: Cannot read property 'LinkedStateMixin' of undefined ` – myusuf May 03 '14 at 07:16
  • 1
    You need to use the React build with addons (`react-with-addons.js`) – jbaiter May 03 '14 at 10:50
  • 11
    you can also use an onSubmit with the form instead of onClick with the button – sai May 22 '14 at 00:26
  • What if I wan to use an uncontrolled input? @jbaiter – Vamsi Pavan Mahesh Jul 23 '15 at 07:37
  • 1
    Controlled Components have potential issues with autocomplete. Ref https://github.com/facebook/react/issues/1159 and https://github.com/facebook/react/issues/2125 – rlovtang Apr 12 '16 at 11:27
  • how to achieve via ES6 react Component way. – ajaykumar Aug 12 '16 at 10:53
  • 137
    Why using a state for each element of the form ? Anyone else thinks this is a bad pattern ? – eveevans Sep 06 '16 at 03:21
  • 7
    Looks like valueLink is deprecated – Matt Broekhuis Sep 29 '16 at 14:40
  • commenting from the future to thank @MattBroekhuis for saving me time on valueLink – swyx Jan 12 '17 at 21:42
  • 5
    Isn't this storing the password in clear text on the client side for the whole time? That doesn't seem really appropriate for a password field. – NewbiZ Jul 27 '18 at 07:49
  • 2
    The downside of this approach is that you're causing a state change everytime the value of the inputs change. If you only need the values when the user submits the form, you should not go with this approach. – Ed Spencer Jul 03 '19 at 08:02
  • 1
    as `this.setState` is asynchrnous, is it possible that the `handleLogin` doesn't retrieve the last value of `this.state.login` or `this.state.password` ? Imagine the user is writing his password and submit immediatly the form, if `setState` is asynchronous it may be executed after the `onSubmit` handler ? – Olivier Boissé Oct 08 '19 at 16:53
  • If I am using redux, it it fine to create a state in component? – rsp Jul 03 '20 at 06:17
  • Is there performance impact on re-rendering? @hoohoo-b answer prevents re-rendering. – Kunal Jul 28 '20 at 21:55
  • the purpose of
    is so you can use e.target.elements, and html build in required props etc, if you are using state, then
    is redundant.
    – Someone Special Feb 12 '21 at 11:55
  • Ah, so this is why React forms sometimes reset themselves after autofill race conditions. Thank you for showing the wrong way to do this. – sfscs Dec 22 '22 at 10:29
62

Adding on to Michael Schock's answer:

class MyForm extends React.Component {
  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    const data = new FormData(event.target);

    console.log(data.get('email')); // Reference by form input's `name` tag

    fetch('/api/form-submit-url', {
      method: 'POST',
      body: data,
    });
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label htmlFor="username">Enter username</label>
        <input id="username" name="username" type="text" />

        <label htmlFor="email">Enter your email</label>
        <input id="email" name="email" type="email" />

        <label htmlFor="birthdate">Enter your birth date</label>
        <input id="birthdate" name="birthdate" type="text" />

        <button>Send data!</button>
      </form>
    );
  }
}

See this Medium article: How to Handle Forms with Just React

This method gets form data only when the Submit button is pressed. It is much cleaner, IMO!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hoohoo-b
  • 1,141
  • 11
  • 12
59

For those who don't want to use ref and reset the state with OnChange event, you can just use simple OnSubmit handle and loop through the FormData object.

Note that you cannot access formData.entries() directly since it is an iterable, you have to loop over it.

This example is using React Hooks:

const LoginPage = () => {
  const handleSubmit = (event) => {
    const formData = new FormData(event.currentTarget);
    event.preventDefault();
    for (let [key, value] of formData.entries()) {
      console.log(key, value);
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="text" name="username" placeholder="Email" />
        <input type="password" name="password" placeholder="Password" />
        <button type="submit">Login</button>
      </form>
    </div>
  );
};

And if you're using TypeScript:

export const LoginPage: React.FC<{}> = () => {
  const handleSubmit: React.FormEventHandler<HTMLFormElement> = (event) => {
    const formData = new FormData(event.currentTarget);
    event.preventDefault();
    for (let [key, value] of formData.entries()) {
      console.log(key, value);
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="text" name="username" placeholder="Email" />
        <input type="password" name="password" placeholder="Password" />
        <button type="submit">Login</button>
      </form>
    </div>
  );
};
Per Enström
  • 902
  • 8
  • 33
CloudWave
  • 913
  • 9
  • 16
51

An alternative approach is to use the ref attribute and reference the values with this.refs. Here is a simple example:

render: function() {
    return (<form onSubmit={this.submitForm}>
        <input ref="theInput" />
    </form>);
},
submitForm: function(e) {
    e.preventDefault();
    alert(React.findDOMNode(this.refs.theInput).value);
}

More info can be found in the React docs: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute

For a lot of the reasons described in How do I use radio buttons in React? this approach isn't always the best, but it does present a useful alternative in some simple cases.

Community
  • 1
  • 1
Jamund Ferguson
  • 16,721
  • 3
  • 42
  • 50
51

There isn't any need to use refs. You can access it using an event:

function handleSubmit(e) {
    e.preventDefault()
    const {username, password } = e.target.elements
    console.log({username: username.value, password: password.value })
}

<form onSubmit={handleSubmit}>
   <input type="text" id="username"/>
   <input type="text" id="password"/>
   <input type="submit" value="Login" />
</form>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sameera K
  • 1,298
  • 1
  • 17
  • 26
24

An easy way to deal with refs:

class UserInfo extends React.Component {

  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();

    const formData = {};
    for (const field in this.refs) {
      formData[field] = this.refs[field].value;
    }
    console.log('-->', formData);
  }

  render() {
    return (
        <div>
          <form onSubmit={this.handleSubmit}>
            <input ref="phone" className="phone" type='tel' name="phone"/>
            <input ref="email" className="email" type='tel' name="email"/>
            <input type="submit" value="Submit"/>
          </form>
        </div>
    );
  }
}

export default UserInfo;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
E. Fortes
  • 1,338
  • 12
  • 12
  • 2
    This method will someday in the future be deprecated. Refs are to only used with callbacks and not strings. For more details: https://facebook.github.io/react/docs/refs-and-the-dom.html – David Labbe Jul 03 '17 at 14:29
  • Cool! :) I like to use `Object.keys()` followed for `map()` like this: `Object.keys(this.refs).map(field => formData[field] = this.refs[field].value)` – Francis Rodrigues Nov 22 '17 at 21:36
  • Yes the string refs are deprecated. A better way to do it right now is to use the onChange callback. If you still want to use refs you could use this synctax: ` { this.textInput = input; }} />` – E. Fortes Nov 23 '17 at 12:34
  • I @E.Fortes, can you please explain the onChange callback method? Thank you very much if you will. Please tag me so I will be informed of your answer. – Simona Adriani Feb 07 '18 at 16:21
  • a simple way would be (sorry the code formatter not working): class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ''}; this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } render() { return (
    ); } }
    – E. Fortes Feb 08 '18 at 21:57
  • You *might* want to use the `FormData` object instead of `{}`. – Fred Apr 05 '18 at 11:16
21

You could switch the onClick event handler on the button to an onSubmit handler on the form:

render : function() {
      return (
        <form onSubmit={this.handleLogin}>
          <input type="text" name="email" placeholder="Email" />
          <input type="password" name="password" placeholder="Password" />
          <button type="submit">Login</button>
        </form>
      );
    },

Then you can make use of FormData to parse the form (and construct a JSON object from its entries if you want).

handleLogin: function(e) {
   const formData = new FormData(e.target)
   const user = {}

   e.preventDefault()

   for (let entry of formData.entries()) {
       user[entry[0]] = entry[1]
   }

   // Do what you will with the user object here
}
Michael Schock
  • 575
  • 5
  • 8
16

If all your inputs / textarea have a name, then you can filter all from event.target:

onSubmit(event){
  const fields = Array.prototype.slice.call(event.target)
      .filter(el => el.name)
      .reduce((form, el) => ({
        ...form,
        [el.name]: el.value,
      }), {})
}

Totally uncontrolled form without onChange methods, value, defaultValue...

Aral Roca
  • 5,442
  • 8
  • 47
  • 78
13

I would suggest the following approach:

import {Autobind} from 'es-decorators';

export class Form extends Component {

    @Autobind
    handleChange(e) {
        this.setState({[e.target.name]: e.target.value});
    }

    @Autobind
    add(e) {
        e.preventDefault();
        this.collection.add(this.state);
        this.refs.form.reset();
    }

    shouldComponentUpdate() {
        return false;
    }

    render() {
        return (
            <form onSubmit={this.add} ref="form">
                <input type="text" name="desination" onChange={this.handleChange}/>
                <input type="date" name="startDate" onChange={this.handleChange}/>
                <input type="date" name="endDate" onChange={this.handleChange}/>
                <textarea name="description" onChange={this.handleChange}/>
                <button type="submit">Add</button>
            </form>
        )
    }

}
James Akwuh
  • 2,169
  • 1
  • 23
  • 25
  • If you'r not rerendering the component, how you can set the value of each element according to the current state? e.g "value={this.state. destination}". Also you can't run react validations on the form if your not rerendering it – Avishay28 Jun 30 '20 at 07:37
12

Here is the shortest way to get data from the form and the best way to avoid id and ref just by using FormData:

import React, { Component } from 'react'

class FormComponent extends Component {
  formSubmit = (event) => {
    event.preventDefault()
    var data = new FormData(event.target)
    let formObject = Object.fromEntries(data.entries())
    console.log(formObject)
  }
  render() {
    return (
      <div>
        <form onSubmit={this.formSubmit}>
          <label>Name</label>
          <input name="name" placeholder="name" />
          <label>Email</label>
          <input type="email" name="email" />
          <input type="submit" />
        </form>
      </div>
    )
  }
}
export default FormComponent
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
arn48
  • 310
  • 4
  • 12
6

More clear example with es6 destructing

class Form extends Component {
    constructor(props) {
        super(props);
        this.state = {
            login: null,
            password: null,
            email: null
        }
    }

    onChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    onSubmit(e) {
        e.preventDefault();
        let login = this.state.login;
        let password = this.state.password;
        // etc
    }

    render() {
        return (
            <form onSubmit={this.onSubmit.bind(this)}>
                <input type="text" name="login" onChange={this.onChange.bind(this)} />
                <input type="password" name="password" onChange={this.onChange.bind(this)} />
                <input type="email" name="email" onChange={this.onChange.bind(this)} />
                <button type="submit">Sign Up</button>
            </form>
        );
    }
}
Sergio Ivanuzzo
  • 1,820
  • 4
  • 29
  • 59
5

Give your inputs ref like this

<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />

Then you can access it in your handleLogin like so:

handleLogin: function(e) {
   e.preventDefault();
    console.log(this.refs.email.value)
    console.log(this.refs.password.value)
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Imran Rafique
  • 1,986
  • 2
  • 12
  • 14
5

I use like this using React Component state:

<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />

handleChange(e){
   this.setState({[e.target.name]: e.target.value})
}`
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adnan Boota
  • 181
  • 2
  • 9
5

For TypeScript users

import react from 'react'

interface FormInterface {
    [key: string]: string
}

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
   event.preventDefault();
   let formData = new FormData(event.currentTarget)
   let formObj: FormInterface = {}
   for (let [key, value] of Array.from(formData.entries())) {
     formObj[key] = value.toString()
   }
};

<form onSubmit={handleSubmit}>
   <input type="text" name="email" placeholder="Email" />
   <input type="password" name="password" placeholder="Password" />
   <button type="submit">Login</button>
</form>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anis
  • 1,190
  • 2
  • 13
  • 26
5

TypeScript will complain if you try Aliaksandr Sushkevich's solution. One workaround can be done using type assertions:

<form
    onSubmit={(e: React.SyntheticEvent) => {
      e.preventDefault();
      const target = e.target as typeof e.target & {
        username: { value: string };
        password: { value: string };
      };
      const username = target.username.value; // typechecks
      const password = target.password.value; // typechecks
      // etc...
    }}
>
<input type="text" name="username"/>
...

Though, this is still just a workaround, because here you are telling TypeScript what to expect. This will break at runtime if you add a value that doesn't have a corresponding input element.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ibrahim.B
  • 128
  • 3
  • 8
4

Also, this can be used too.

handleChange: function(state,e) {
  this.setState({[state]: e.target.value});
},
render : function() {
  return (
    <form>
      <input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this, 'email')} />
      <input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handleChange.bind(this, 'password')}/>
      <button type="button" onClick={this.handleLogin}>Login</button>
    </form>
  );
},
handleLogin: function() {
  console.log("EMail: ", this.state.email);
  console.log("Password: ", this.state.password);
}
Pramesh Bajracharya
  • 2,153
  • 3
  • 28
  • 54
Yurii Kosygin
  • 57
  • 1
  • 2
4

If you are using Redux in your project, you can consider using the higher order component redux-form.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ivks
  • 109
  • 1
  • 6
4

In many events in JavaScript, we have event which gives an object, including what event happened and what are the values, etc.

That's what we use with forms in React as well.

So in your code you set the state to the new value. Something like this:

class UserInfo extends React.Component {

  constructor(props) {
    super(props);
    this.handleLogin = this.handleLogin.bind(this);
  }

  handleLogin(e) {
    e.preventDefault();
    for (const field in this.refs) {
      this.setState({this.refs[field]: this.refs[field].value});
    }
  }

  render() {
    return (
        <div>
          <form onSubmit={this.handleLogin}>
            <input ref="email" type="text" name="email" placeholder="Email" />
            <input ref="password" type="password" name="password" placeholder="Password" />
            <button type="button">Login</button>
          </form>
        </div>
    );
  }
}

export default UserInfo;

Also this is the form example in React v.16, just as reference for the form you creating in the future:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alireza
  • 100,211
  • 27
  • 269
  • 172
3

This might help Meteor (v1.3) users:

render: function() {
    return (
        <form onSubmit={this.submitForm.bind(this)}>
            <input type="text" ref="email" placeholder="Email" />
            <input type="password" ref="password" placeholder="Password" />
            <button type="submit">Login</button>
        </form>
    );
},
submitForm: function(e) {
    e.preventDefault();
    console.log( this.refs.email.value );
    console.log( this.refs.password.value );
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Joe L.
  • 4,433
  • 1
  • 19
  • 14
3

To improve the user experience; when the user clicks on the submit button, you can try to get the form to first show a sending message. Once we've received a response from the server, it can update the message accordingly. We achieve this in React by chaining statuses. See codepen or snippets below:

The following method makes the first state change:

handleSubmit(e) {
    e.preventDefault();
    this.setState({ message: 'Sending...' }, this.sendFormData);
}

As soon as React shows the above Sending message on screen, it will call the method that will send the form data to the server: this.sendFormData(). For simplicity I've added a setTimeout to mimic this.

sendFormData() {
  var formData = {
      Title: this.refs.Title.value,
      Author: this.refs.Author.value,
      Genre: this.refs.Genre.value,
      YearReleased: this.refs.YearReleased.value};
  setTimeout(() => { 
    console.log(formData);
    this.setState({ message: 'data sent!' });
  }, 3000);
}

In React, the method this.setState() renders a component with new properties. So you can also add some logic in render() method of the form component that will behave differently depending on the type of response we get from the server. For instance:

render() {
  if (this.state.responseType) {
      var classString = 'alert alert-' + this.state.type;
      var status = <div id="status" className={classString} ref="status">
                     {this.state.message}
                   </div>;
  }
return ( ...

codepen

Hom Bahrani
  • 3,022
  • 27
  • 25
3
 onChange(event){
     console.log(event.target.value);
  }
  handleSubmit(event){ 
    event.preventDefault();
    const formData = {};
      for (const data in this.refs) {
        formData[data] = this.refs[data].value;
      }
    console.log(formData);
  }



 <form onSubmit={this.handleSubmit.bind(this)}>
  <input type="text" ref="username" onChange={this.onChange} className="form-control"/>
  <input type="text" ref="password" onChange={this.onChange} className="form-control"/>
  <button type="submit" className="btn-danger btn-sm">Search</button>
 </form>

Output image attached here

Milan Panigrahi
  • 546
  • 9
  • 11
  • 1
    Please provide an explanation as well. – BlackBeard Jan 08 '18 at 11:55
  • 2
    I'll try to explain this, which I found brilliant. In the handleSubmit() function you are building an object (formData) in which the key is the 'ref' attribute of every input in the form (the 'formData[data]' statement), and the value is the value of the input with this 'ref' attribute (the 'this.refs[data].value' statement). With 'formData[data] = this.refs[data].value' you are building this object. You are saying, literally: formData['username'] = (the value of username input) and formData['password'] = (the value of password input) Output will be: {user: 'blablabla', password: 'xxx'} – Simona Adriani Feb 07 '18 at 16:09
  • Thank you @SimonaAdriani for you explanation . – Milan Panigrahi Feb 19 '18 at 10:41
3

This is an example of dynamically added fields. Here form data will store by input name key using a React useState hook.

import React, { useState } from 'react'

function AuthForm({ firebase }) {
    const [formData, setFormData] = useState({});

    // On Form Submit
    const onFormSubmit = (event) => {
        event.preventDefault();
        console.log('data', formData)
        // Submit here
    };

    // get Data
    const getData = (key) => {
        return formData.hasOwnProperty(key) ? formData[key] : '';
    };

    // Set data
    const setData = (key, value) => {
        return setFormData({ ...formData, [key]: value });
    };

    console.log('firebase', firebase)
    return (
        <div className="wpcwv-authPage">
            <form onSubmit={onFormSubmit} className="wpcwv-authForm">
                <input name="name" type="text" className="wpcwv-input" placeholder="Your Name" value={getData('name')} onChange={(e) => setData('name', e.target.value)} />
                <input name="email" type="email" className="wpcwv-input" placeholder="Your Email" value={getData('email')} onChange={(e) => setData('email', e.target.value)} />
                <button type="submit" className="wpcwv-button wpcwv-buttonPrimary">Submit</button>
            </form>
        </div>
    )
}

export default AuthForm
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shapon Pal
  • 1,098
  • 3
  • 16
  • 27
2

The simplest solution that came to my mind is this:

<form onSubmit={(e) => handleLogin(e)}>
    <input type="text" name="email" placeholder="Email" />
    <input type="password" name="password" placeholder="Password" />
    <button type="submit">Login</button>
</form>

Your handle fuction:

const handleLogin = (e) => {
    e.preventDefault()
    const data = {
        email: e.target.elements.email.value,
        password: e.target.elements.password.value
    }
    console.log('FormData: ', data)
}

When you click on your login button you will see FormData in console in this format: FormData: {email: 'whatever you tiped here', password: 'also whatever you tiped here'}.

e.target.elements.email.value targets elements with specific name, in your case it is email and password.

After console.log in handleLogin, you can do some verification logic and login logic.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

If you have multiple occurrences of an element name, then you have to use forEach().

HTML

  <input type="checkbox" name="delete" id="flizzit" />
  <input type="checkbox" name="delete" id="floo" />
  <input type="checkbox" name="delete" id="flum" />
  <input type="submit" value="Save"  onClick={evt => saveAction(evt)}></input>

JavaScript

const submitAction = (evt) => {
  evt.preventDefault();
  const dels = evt.target.parentElement.delete;
  const deleted = [];
  dels.forEach((d) => { if (d.checked) deleted.push(d.id); });
  window.alert(deleted.length);
};

Note the dels in this case is a RadioNodeList, not an array, and is not an Iterable. The forEach() is a built-in method of the list class. You will not be able to use a map() or reduce() here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeff Lowery
  • 2,492
  • 2
  • 32
  • 40
1
const HandleSubmit = (e) => {
    e.preventDefault();
    let formData = e.target[0].form;
        axios({
            url: 'http://localhost:4000/data/add',
            method: 'POST',
            data: new FormData(formData)
        }).then(async (data) => {
            await toastr.success('Added Successfully', {
                timeOut: 1000,
            });
            await setTimeout(() => {
                window.location.reload();
            }, 1000)

        })
    }
0

I think this is also the answer that you need. In addition, Here I add the required attributes. onChange attributes of Each input components are functions. You need to add your own logic there.

handleEmailChange: function(e) {
    this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
   this.setState({password: e.target.value});
},
formSubmit : async function(e) {
    e.preventDefault();
    // Form submit Logic
  },
render : function() {
      return (
        <form onSubmit={(e) => this.formSubmit(e)}>
          <input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} required />
          <input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} required />
          <button type="button">Login</button>
        </form>);
},
handleLogin: function() {
    //Login Function
}
Sabesan
  • 654
  • 1
  • 10
  • 17
0
<form onSubmit={handleLogin}>
    <input type="text" name="email" placeholder="Email" />
    <input type="text" name="password" placeholder="Password" />
    <button type="submit">Login</button>
</form>
const handleLogin = (event) => {
    event.preventDefault();
    console.log(event.target[0].value)
    console.log(event.target[1].value)
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vikrant
  • 9
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 22 '22 at 08:59
0

This will be the easiest method:

const formValidator = (form) => {
    let returnData = {}
    console.log(form.length);

    for (let i = 0; i < form.length; i++) {
        const data = form[i]
        if (data.name != null && data.name != "") {
            returnData[data.name] = data.value;
        }
    }
    return returnData
}

In the form, simply use:

<form onSubmit={(e) => {
        e.preventDefault()
        let data = formValidator(e.currentTarget)
    }}>
    <RoundTextFiled name='app-id' style={{ marginTop: '10px', borderRadius: '20px' }} label="App id" fullWidth required />
    <RoundTextFiled name='api-hash' style={{ marginTop: '5px' }} label="Api hash" fullWidth required />
    <RoundTextFiled name='channel-id' style={{ marginTop: '5px' }} label="Channel id" fullWidth required />
    <Button type='submit' variant="contained" fullWidth style={{ padding: '10px', marginTop: '5px', borderRadius: '10px' }}>Login</Button>
</form>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adhil mhdk
  • 89
  • 2
  • 9
0

Here is my approach for collecting multiple form inputs using single inputChangeHandler

import React from "react";

const COLORS = ["red", "orange", "yellow", "purple", "green", "white", "black"];

export default function App() {

  const initialFormFields = {
    name: undefined,
    email: undefined,
    favourite_color: undefined
  };
  const [formInput, setFormInput] = React.useState(initialFormFields);

  function inputChangeHandler(event) {
    setFormInput(prevFormState => ({
      ...prevFormState,
      [event.target.name]: event.target.value
    }))
  };

  return (
    <div className="App">
      <form>
        <label>Name: <input name="name" type="text" value={formInput.name} onChange={inputChangeHandler}/></label>
        <label>Email: <input name="email" type="email" value={formInput.email} onChange={inputChangeHandler}/></label>
        <div>
          {COLORS.map(color => <label><input type="radio" name="favourite_color" value={color} key={color} onChange={inputChangeHandler}/> {color} </label>)}
        </div>
      </form>

      <div>
        Entered Name: {formInput.name}
        Entered Email: {formInput.email}
        Favourite Color: {formInput.favourite_color}
      </div>
    </div>
  );
}
Sachin Som
  • 1,005
  • 3
  • 8
-1

Use:

import { useState } from 'react'

export default function App() {
    const [data, setData] = useState({})

    const updateData = e => {
        setData({
            ...data,
            [e.target.name]: e.target.value
        })
    }

    const submit = e => {
        e.preventDefault()
        console.log(data)
    }

    return (
        <form onSubmit={submit}>
            <input
                name="email"
                type="email"
                onChange={updateData}
            />
            <input
                name="password"
                type="password"
                onChange={updateData}
             />
            <button>Submit</button>
        </form>
    )
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 22 '23 at 11:10