Ilja
Ilja

Reputation: 46479

Using Form and Input elements correctly

I'm trying to make reusable Form and Input components and so far got to following:

Form

import React from 'react'
import classNames from 'classnames/bind'
import styles from './style.scss'

const cx = classNames.bind(styles)

export default class Form extends React.Component {
  constructor (props) {
    super(props)
    this.submitForm = this.submitForm.bind(this)
  }

  submitForm (e) {
    e.preventDefault()
    this.props.onSubmit()
  }

  render () {
    return (
      <form className={cx('Form')} onSubmit={this.submitForm}>
        {this.props.children}
      </form>
    )
  }
}

Form.propTypes = {
  children: React.PropTypes.any.isRequired,
  onSubmit: React.PropTypes.func.isRequired
}

Input

import React from 'react'
import classNames from 'classnames/bind'
import styles from './style.scss'

const cx = classNames.bind(styles)

export default class Input extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      value: this.props.value || ''
    }
    this.changeValue = this.changeValue.bind(this)
  }

  changeValue (e) {
    this.setState({value: e.target.value})
  }

  render () {
    return (
      <div className={cx('Input')}>
        <input
          type={this.props.type}
          value={this.state.value}
          required={this.props.required}
          onChange={this.changeValue}
          placeholder={this.props.placeholder || ''}
          noValidate />
      </div>
    )
  }
}

Input.propTypes = {
  type: React.PropTypes.string.isRequired,
  value: React.PropTypes.string,
  required: React.PropTypes.bool,
  placeholder: React.PropTypes.string
}

I then use them within some another component, lets say HomePageComponent

<Form onSubmit={this.loginUser}>
  <Input type='email' placeholder='email' />
  <Input type='password' placeholder='password' />
  <Input type='submit' value='Submit' />
</Form>

This all works well, but how would I get input values and use them to set state of HomePageComponent to this.state= { email: [value from input email], password: [value from password input] }

Upvotes: 0

Views: 77

Answers (2)

link0047
link0047

Reputation: 103

if you add the name attribute to your input elements, you can access their values this way. Hope this helps

import React, { PropTypes, Component } from 'react';
class Form extends Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  
  handleSubmit(e) {
    e.preventDefault();
    const form = e.target.elements;
    console.log(form.email.value);
    console.log(form.password.value);
  }
  
  render() {
    return (
      <form className={cx('Form')} onSubmit={this.handleSubmit}>
        <Input type='email' placeholder='email' name='email' />
        <Input type='password' placeholder='password' name='password' />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

Upvotes: 0

Gosha A
Gosha A

Reputation: 4570

You don't need to store the value in the Input component.

You can get the input values by keeping references to individual inputs:

<Form onSubmit={this.loginUser}>
  <Input ref='email' type='email' placeholder='email' />
  <Input ref='password' type='password' placeholder='password' />
  <Input type='submit' value='Submit' />
</Form>

Then, in loginUser you can access these using:

const email = ReactDOM.findDOMNode(this.refs.email).value;
const password = ReactDOM.findDOMNode(this.refs.password).value;

Upvotes: 1

Related Questions