-1

Given the source code for a simple login form, see below. You see I want to use the username text field's value when I click the form's submit button. Since I need a reference to the actual DOM node to retrieve the value, I'm setting the usernameElement variable to that node.

const Login = ({ onLogin }) => {
  let usernameElement

  const handleSubmit = event => {
    event.preventDefault()
    onLogin(usernameElement.value)
  }

  return <form onSubmit={handleSubmit}>
    <input
      type="text"
      name="username"
      ref={node => { usernameElement = node }}
    />
    <button type="submit">Login</button>
  </form>
}

So, how would I make an functional approach to that problem, or simply get rid of the let variable?

sk22
  • 837
  • 1
  • 10
  • 21
  • 1
    Use states. Change value every time someone types in input. – Oen44 Jun 27 '17 at 09:49
  • See this answer https://stackoverflow.com/questions/44473449/react-multiple-input-reference/44473720#44473720 – Shubham Khatri Jun 27 '17 at 09:51
  • What would be wrong here with `onLogin( event.target.querySelector('[name=username]').value );` besides ignoring the "that's how we do it in React" policy. *I'm not talking about a big app, but just this tiny component not using any sub-components.* – Thomas Jun 27 '17 at 10:13
  • @Thomas I'm not sure if I'd be comfortable using querySelector/getElementBy* while developing a React app... But, you're right, I mean, why not? – sk22 Jun 27 '17 at 11:46
  • Why would you consider it an improvement to search the DOM instead of using the approach you already have, which works fine? – Tom Fenech Jun 27 '17 at 17:33

1 Answers1

0

Apparently, the correct approach to this is to make use of the component's state, meaning you need a stateful component instead of the stateless one.

// untested
class Login extends Component {
  state = { username: '' }

  handleChange = event => {
    this.setState({ username: event.target.value })
  }

  handleSubmit = event => {
    event.preventDefault()
    this.props.onLogin(this.state.username)
  }

  render = () =>
    <form onSubmit={this.handleSubmit}>
      <input
        type="text"
        name="username"
        value={this.state.username}
        onChange={this.handleChange}
      />
      <button type="submit">Login</button>
    </form>
}

Using this, the username is always bound to this.state.username. The handleSubmit method can just use the username from the component's state.

See this page for further information: https://facebook.github.io/react/docs/forms.html

sk22
  • 837
  • 1
  • 10
  • 21