Leon Gaban
Leon Gaban

Reputation: 39018

How to get form data from input fields in React

The constructor and function:

constructor(props) {
    super(props);

    this.state = {
        tagline: 'We rank what people are talking about.',
        year: new Date().getFullYear()
    };

    this.onFormSubmit = this.onFormSubmit.bind(this);
}

onFormSubmit(e) {
    console.log('onFormSubmit', e)
    console.log('this.state', this.state);
};

The form (classNames removed for clarity):

<form onSubmit={ this.onFormSubmit }>
    <div className="fl w100">
        <div>
            <input type="text" id="email" value={ this.state.email }/>
            <label htmlFor="email">Email</label>
        </div>
    </div>

    <div className="fl w100">
        <div>
            <input type="password" id="password" value={ this.state.password }/>
            <label htmlFor="password">Password</label>
        </div>
    </div>

    <button type="submit">
        Login
    </button>
</form>

This is what logs out, note no email or password information:enter image description here

Full Login component code


import React from 'react';

class Login extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            tagline: 'We rank what people are talking about.',
            year: new Date().getFullYear()
        };

        this.onFormSubmit = this.onFormSubmit.bind(this);
    }

    onFormSubmit(e) {
        console.log('onFormSubmit', e)
        console.log('this.state', this.state);
    };

    render() {
        return (<div className="app">
            <div className="welcome">
                <header>
                    <div className="wikitags-logo">
                        <img src="imgs/wikitags-logo.png"/>
                    </div>
                    <h2>Admin Portal</h2>
                    <p>{ this.state.tagline }</p>
                </header>

                <section className="login-form">
                    <form onSubmit={ this.onFormSubmit }>
                        <div className="fl w100">
                            <div className="mdl-textfield mdl-js-textfield">
                                <input className="mdl-textfield__input" type="text" id="email" value={ this.state.email }/>
                                <label className="mdl-textfield__label" htmlFor="email">Email</label>
                            </div>
                        </div>

                        <div className="fl w100">
                            <div className="mdl-textfield mdl-js-textfield">
                                <input className="mdl-textfield__input" type="password" id="password" value={ this.state.password }/>
                                <label className="mdl-textfield__label" htmlFor="password">Password</label>
                            </div>
                        </div>

                        <button type="submit" className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
                            Login
                        </button>
                    </form>
                </section>

                <footer>
                    &copy; { this.state.year } WikiTags
                </footer>
            </div>
        </div>);
    }
}

export default Login;

Upvotes: 9

Views: 40231

Answers (3)

bntzio
bntzio

Reputation: 1324

You are not getting email or password information because you're passing in the state console.log('this.state', this.state); and you haven't set a state for the email and password.

Now, you got two options:

  1. Set the state and get the form info from there
  2. Pass the input value to a function that handles the info

For option 1, you'll need to set a state for your email and password (although setting a state for a password is not recommended) and an onChange event handler on the input(s).

Set up your onChange event handlers.

<form onSubmit={ this.onFormSubmit }>
  <input type="text" id="email" onChange={this.handleEmailChange} value={ this.state.email } />

  <input type="password" id="password" onChange={this.handlePasswordChange} value={ this.state.password } />

  <button type="submit">
    Login
  </button>
</form>

And the functions to set the email and password states.

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

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

And don't forget to initialize the state for your email and password in the constructor and bind the functions.

constructor(props) {
  super(props);

  this.state = {
    email: '',
    password: ''
  };

  this.handleEmailChange = this.handleEmailChange.bind(this);
  this.handlePasswordChange = this.handlePasswordChange.bind(this);
}

And you're done! Then on the onFormSubmit function just access the email and password values from the state this.state.email and this.state.password and do whatever you like.

Now for option 2, you can just pass in the event.target.value of the inputs, those are the values for the email and the password, and pass those values to a form event handler onSubmit function, from there you can do whatever you want (set the state or update the email and password, change them, whatever).

<form onSubmit={ this.onFormSubmit }>
  <input type="text" id="email" name="theEmail" />

  <input type="password" id="password" name="thePassword" />

  <button type="submit">
    Login
  </button>
</form>

And the onFormSubmit function.

onFormSubmit(event) {
  const email = event.target.theEmail.value;
  const password = event.target.thePassword.value;

  // do stuff
  console.log('Email:', email);
  console.log('Password:', password);
};

The easier and recommended way to accomplish what you're trying to do is the option 2.

Remember, the less state your app handles the better.

Upvotes: 6

Mayank Shukla
Mayank Shukla

Reputation: 104359

Suggestions:

1. You are using value property with input fields but you didn't defined the onChange method so your input fields will be read-only because state value will not get updated.

2. You need to define a onChange event will all the input fields or make them uncontrolled element by removing the value property.

3. In case of uncontrolled element define the ref to each field and to access the value use this.ref_name.value.

By Defining the onChange event:

Define the name property to each input element (name should be same as state variable name it will help to update the state and we can handle all the change in single onChange function) like this:

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

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

By Uncotrolled element:

<input type="text" ref={el => this.el = el} />

Now inside onSubmit function use this.el.value to access he values of this input field.

Check this answer for reference: https://stackoverflow.com/a/43695213/5185595

Upvotes: 11

Nitsew
Nitsew

Reputation: 3662

So how I would approach this is to store the values in your state using what is called a controlled component. Making a controlled component is very simple, this is a basic implementation:

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>
    );
  }
}

The key here is the handleChange function, and the onChange attribute. Every time the input field changes, the handleChange function is going to be called and the state will be updated.

You can find more info form the documentation here: https://facebook.github.io/react/docs/forms.html

Upvotes: 2

Related Questions