I went through the docs of react, about controlled and uncontrolled components. I have created a simple use case where I want to enforce the user to enter only uppercase values in the input field.
In the first case I have used 'ref' with 'onChange' to achieve this and a global object's property to capture the dom node.Here's the code for that - https://jsfiddle.net/69z2wepo/78064/
class Nikhil extends React.Component {
constructor(props){
super(props);
this.field = {
input: ''
};
}
foo() {
this.y = this.field.input;
this.y.value = this.y.value.toUpperCase();
}
render() {
return (
<div>
<input ref={ node => this.field.input = node } onChange={ this.foo.bind(this) }/>
</div>
);
}
}
ReactDOM.render(<Nikhil/>,container);
In the second case I have used 'value' property and state with'onChange'. Here's the code for that -https://jsfiddle.net/69z2wepo/78066/
class Nikhil extends React.Component {
constructor(props){
super(props);
this.state = {
input: ''
};
}
foo(e) {
this.setState({ input: e.target.value.toUpperCase() });
}
render() {
return (
<div>
<input value= { this.state.input } onChange={ this.foo.bind(this) }/>
</div>
);
}
}
ReactDOM.render(<Nikhil/>,container);
The docs says:
With a controlled component, every state mutation will have an
associated handler function. This makes it straightforward to
modify or validate user input. For example, if we wanted to enforce
that names are written with all uppercase letters, we could write
handleChange as:
handleChange(event) {
this.setState({ value: event.target.value.toUpperCase()} );
}
Well I can validate the user input even when I am not using state, and not syncing the value prop with state , as done in the first example above.
So definitely validating user input can be done without using state at all ?
Can you explain why one approach is better than the other ?
What exactly the 'single source of truth' means and why it is so important ?
In both the cases I am using a global variable of the component which is an object and can be accessed throughout the component.
- Also why should I unnecessarily use value = { this.state.input } in example 2, because that would call render on every keystroke, whereas in case 1 render is called only once. So isn't performance in case 1 better than 2 ?
Also from the docs:
To write an uncontrolled component, instead of writing an
event handler for every state update, you can use a ref to get
form values from the DOM
Well I need to write an event handler like 'onChange' even when using 'ref' to validate user input at run time as done in case 1. So using event handler with 'ref' is normal ?
Use case for state variable -- From my understanding the only case where I have no other option than to use state variable is when I need to update the view dynamically. Because this.setState() calls render every time it is run . Here's the code for that -https://jsfiddle.net/69z2wepo/78068/
class Nikhil extends React.Component {
constructor(props){
super(props);
this.state = {
input: ''
};
}
foo(e) {
this.setState({ input: e.target.value });
}
render() {
return (
<div>
<input onChange={ this.foo.bind(this) }/>
<p>{ this.state.input }</p>
</div>
);
}
}
ReactDOM.render(<Nikhil/>,container);
I will be grateful if someone could clarify on all the three examples and enhance my understanding of the above concepts.