1

I read the answers on this question but none is similar to my set up:

What are controlled components and uncontrolled components?

I have a parent component and many children as inputs. Each input has a defaultValue that is set using a prop received from the parent and the validation of the input is performed on onBlur. This is because the validation is asynchronous, so onChange would slow down the app like crazy.

How is this orchestration called? The traditional definition for "controlled" seems to be an input which updates on every onChange, while an "uncontrolled" input is one which manages its own internal state, which is later accessed via a ref. My set up seems to fall short of both, sitting somewhere in the middle - or not?

Update: Here's a CodeSandbox.

Paul Razvan Berg
  • 16,949
  • 9
  • 76
  • 114
  • 1
    It would be helpful for you to post some actual code for us to look at. But fundamentally, "controlled" just means that React stores the state of the form in state and the HTML is rendered based off of that. "Uncontrolled" means that the form values are not stored in React state but only the DOM itself, which is a bad because React should be the "source of truth" for what the values are. Whether your onChange handlers are synchronous or not is irrelevant. https://reactjs.org/docs/uncontrolled-components.html – jered Dec 05 '19 at 23:27
  • Thanks for your comment, @jered. I updated the question with a link to a CodeSandbox. – Paul Razvan Berg Dec 06 '19 at 00:02

1 Answers1

1

If I understand your setup correctly, your inputs are uncontrolled, because their state is held in the DOM rather than in React state. Validation is a separate concern, which can happen synchronously or asynchronously. You can let React state hold the values whatever you do for validation. Note that most of the time you don't want to prevent the input from even having an invalid value - you just want to ensure that the user can't submit the form while the values are invalid. Thus you can have an onChange handler to set some value on state as in the following:

<input type="text" 
  value={this.state.myValue} 
  onChange={val => this.setState({myValue: val}, 
    ()=> this validateMyValue(this.state.myValue))}} />

this.validateMyValue could be asynchronous, and do whatever is required if validation fails. That would be a controlled component doing what you want.

see sharper
  • 11,505
  • 8
  • 46
  • 65
  • Thanks, see. Unfortunately, I did exactly this before and my app was still very, very slow. – Paul Razvan Berg Dec 06 '19 at 00:03
  • OK, so the performance problem is something else. Async calls shouldn't slow things down anyway, since they are, well, async. Are you saying the app is slow either way? – see sharper Dec 06 '19 at 00:31
  • 1
    Took a look at the code - so I understand you better now. Agree that onBlur may be the best place to validate in this case. But this has noting to do with uncontrolled or controlled inputs per your question. – see sharper Dec 06 '19 at 00:35
  • I know, so maybe I shouldn't have mentioned validation at all in the question. Sorry for that. so, bottom line, this is an uncontrolled input, because it manages its own state until onBlur gets triggered at some later stage? – Paul Razvan Berg Dec 06 '19 at 01:07
  • It really has nothing to do with the onBlur - validation is information *about* the input state, it's not the state itself. The input is uncontrolled because you don't have the binding of `value` to `state`, with `onChange` updating state. That is what "controlled" means. – see sharper Dec 06 '19 at 02:34