2

How do I get around the anti-pattern with state from props when using default values for input fields?

When the form is rendered, it should contain some default values. When I set some values and closes the form and then re-opens the form I want the default values to show, not the ones previously entered...

But when I let state inherit values from props, the props are changed forever. I haven't found a way to get around this.

Andre Pena
  • 56,650
  • 48
  • 196
  • 243
MikaelL
  • 364
  • 1
  • 3
  • 14

1 Answers1

0

If you look at the default input component, or the inputs from react-bootstrap, or most of the DatePickers and Selects on the internet, you will see that most of them have a value prop, and most of them will have little to none state, at least when it comes to the selected value.

An input is meant to be uncontrolled, meaning that they are better off not having state, and just receiving the value as a prop, as well as a callback they should call when the value changes. It's up to the controller-view above them, to watch these events and change the model. Some times it may be convenient for the inputs to keep the value in the state as well, but they can only do it as long as they respect new value being passed as a prop, because the state persists in rerenders and getInitialState is only called once. See also: ReactJS: Why is passing the component initial state a prop an anti-pattern?

However, because it would be too cumbersome for the controller-view to handle all these value changes, React comes with an utility called ReactLink, which is, very briefly, a way to automatically bind an input to a property in the state of the controller-view. Example: You can bind an input to the property DateOfBirth of the model, which is part of the state of the controller-view.

Now back to your question, you don't actually pass the default value, you pass the value itself, as a prop. The controller-view should decide what it is. What is the value for the DateOfBirth field? None? Ok, I'll pass the default value as the value prop.

Community
  • 1
  • 1
Andre Pena
  • 56,650
  • 48
  • 196
  • 243
  • Thank you for an elaborate response. I'm having problem wrapping my head around is this: handling the updated data from an input must be stored in state. Right? So to get around the state-from-props problem I could initially set the value of the input to the value of the prop and then store the updated value in state. But then I have data spread across props and state which is a problem when I want to submit the data. The anti-pattern way (that would make more sense if it'd worked), is to let state inhering the values from props. But that permanently alters the value of the props. – MikaelL Aug 12 '15 at 08:20