React: Docs request: Detailed best practices for form validation with React.

Created on 29 Apr 2016  路  5Comments  路  Source: facebook/react

It's really awesome that the docs contain a special section on forms. I've written up the pain points of dealing with inputs and hopefully highlighting places where React can ease some of that. http://codepen.io/kevinSuttle/post/the-current-state-of-web-forms

Most helpful comment

This is React top-down data flow:

  • Your component maintains some state
  • It passes this state as a prop down to another component
  • That component passes it as a prop down to another component
  • ...

This way it鈥檚 easy to trace any prop up the tree to the state it originated from.
This is the case described in https://facebook.github.io/react/docs/forms.html#controlled-components.

On the other hand, this is an anti-pattern:

  • Your component maintains some state
  • It passes this state as a prop down to another component
  • That component passes it as a prop down to another component which uses this prop to initialize its own state
  • It passes that own state down as a prop to another component
  • ...

This is the case described in https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html. It is an anti-pattern because the bold part is where you can get out of sync issues, and everything below that component may potentially receive props that are out of sync.

Summary:

  • Passing props to children based on own state is good
  • Basing own state on own props is generally not good

All 5 comments

The best practices for form validation are the same as our best practices for React in general. One-way data flow, create reusable components, etc. I don't think we have any opinions that are specific to form validation.

Well, let me give you an example.

From the React docs on controlled form components:

In this example, we are accepting the value provided by the user and updating the value prop of the component.

handleChange: function(event) {
    this.setState({value: event.target.value.substr(0, 140)});
  }

This isn鈥檛 updating props.

Right after that, it says:

A Controlled component does not maintain its own internal state; the component renders purely based on props.

Am I missing something? A component using this pattern owns _only_ its internal state. Form inputs are special, because they usually validate their own state.

Because this is what happens based on that pattern, where state comes out the winner, because you鈥檙e not actually updating props.

screen shot 2016-05-02 at 1 33 26 pm

screen shot 2016-05-02 at 1 41 14 pm

This contradicts the major no-no listed in the best practices, and definitely isn't a "one-way data flow".
https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html

This isn鈥檛 updating props.

It is updating this.state.value which is a prop to the input:

  render: function() {
    return (
      <input
        type="text"
        value={this.state.value} // <--- here

When the docs talk about controlled and uncontrolled components, they mean <input>s and other DOM components themselves鈥擾not_ user鈥檚 components.

In this example <input> is a controlled component because it receives its value as a prop. If it wasn鈥檛 controlled, it would maintain _its own_ state (invisible to you) that you would be unable to modify from inside _your_ parent component鈥攚hich is why it would be uncontrolled.

This is React top-down data flow:

  • Your component maintains some state
  • It passes this state as a prop down to another component
  • That component passes it as a prop down to another component
  • ...

This way it鈥檚 easy to trace any prop up the tree to the state it originated from.
This is the case described in https://facebook.github.io/react/docs/forms.html#controlled-components.

On the other hand, this is an anti-pattern:

  • Your component maintains some state
  • It passes this state as a prop down to another component
  • That component passes it as a prop down to another component which uses this prop to initialize its own state
  • It passes that own state down as a prop to another component
  • ...

This is the case described in https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html. It is an anti-pattern because the bold part is where you can get out of sync issues, and everything below that component may potentially receive props that are out of sync.

Summary:

  • Passing props to children based on own state is good
  • Basing own state on own props is generally not good

Thanks for such a detailed response, @gaearon. Really appreciate it.

Was this page helpful?
0 / 5 - 0 ratings