I was going through React ā lately and recently I figured this thing about writing inputs who's mere logic in React was quite intimidating šØ for me as I was coming from just HTML background and things were quite simple there, isn't it? š¤·āāļø This was the same question in my mind couple of days ago and in the midst of writing a post on CSS (which is upcoming next!), I pulled off some time to explain this simple but frightening at first process of React. š„³
I am sure, you might be thinking instead of just writing good-looking and semantic HTML like below, why shall we need to have these concepts, in the first place. š
<label>
<input type="text"> I š HTML
</label>
Earlier when we had the vanilla JS way of doing things as we used to select the classname of input element above and do our plain old job of getting its value from the target property inside event.
But about time we see how much important forms are for websites and almost every other website today has a call-to-action form intact so we needed to assert more power over the form inputs. šŖ
As you might have seen, React has this feeling of having all HTML inside its body and it respects the writing language of the web šø so it gives us two ways in which we can build forms, one the conventional way known as š© Uncontrolled Inputs, other the powerful one called š© Controlled Inputs.
š©āš» ProTip: You can understand with utmost clarity if you open your React dev tools ā along side writing this code, so you can always refer them to know what current state is.
Grab a slice of pizza, coz it's gonna be over before you finish yours.
This is where we get to keep the traditional way of writing HTML inputs and guess what, it's pretty much the same as the above code snippet, refer below.
class Box extends React.Component (
render() {
return (
<label>
<input type="text" /> I š HTML
</label>
);
}
)
But there's one catch. How to access the input? React gave us a dope way of doing that too! š„³
Refs provide a way to access DOM nodes or React elements created in the render method.
So ref
is nothing but an attribute like we had in HTML and it also provides a way for us to get access to the DOM so that we can get the user typed data from the input. Let's see how. š
class Box extends React.Component {
fluffy = React.createRef()
letsChange = () => {
console.log(this.fluffy.current.value) // input value gets logged
}
render() {
return (
<label>
<input type="text" ref={this.fluffy} onChange={this.letsChange} />
I š HTML
</label>
)
}
Ref
in your input you need to first initialize ref method in your class, by just calling React.createRef()
. We named it fluffy
here. šŗ We'll mention that inside our ref
attribute inside input tag, like above.onChange
which is required whenever there is some kind of change.letsChange
which is called when there is some changes in input, we get the input value by this.fluffly.current.value
. This gives us the text user typed, we can choose to use it however we want.And this is all about, Uncontrolled Inputs. Did you finish your pizza, yet? š
This gives all the power to your plain old input forms. This is the de facto standard of creating forms in React. It's called controlled in first place, because we are controlling its state ourselves. We need to store it's value inside the state object and keep it updated in real time as well, as the user types. So let's get our hands dirty now. š
class Box extends React.Component {
state = { fluffy: "" }
letsChange = (event) => {
this.setState({
fluffy: event.target.value
})
}
render() {
return (
<label>
<input type="text" value={this.state.fluffy} onChange={this.letsChange} />
</label>
)
}
}
Yes, we're now unstoppable. š¤ Now let's understand the flow of the above process.
state
object and store an empty key named fluffy
which will store the user input as he types.onChange
attribute to input which calls letsChange
. This is the callback which occurs first when user makes the tiniest of changes.letsChange
we are passing our all-time favourite argument event
which is used to set the state so that we can see it on the screen.fluffy
to the screen, so we create a value
attribute in input tag as per HTML guidelines and store the fluffy
value inside it.Hence, this above process takes place everytime any change is made by the user, by mutating the state object. šØ
This method gives us enourmous control over the state, šŖ which in turn gives us power over the input. To see this, you can remove or comment out the letsChange
function and try typing in the box? You'll see nothing get input! Why is that? š²
It is such, coz the input box directly renders the text stored inside state which comes through the letsChange
function. Hence, this system allows us to filter the values provided by the user before displaying on the screen itself. Let's say you want to do some sort of custom validation for the user data, you can easily put the code into the letsChange
function and see the magic. š«
// ...
letsChange = (event) => {
let input = event.target.value
input = input.replace(/[0-9]/g, "")
this.setState({ fluffy: input })
}
// ...
You'll not be able to input any numbers in the input, coz the letsChange
function replaces them with empty strings ""
as soon you type something. You can also have a button which can be activated only if some specific conditions are satisfied. The possibilites are endless. š¤
If that doesn't make sense, let me give you another example of this type. šāāļø
Let's say we need a dropdown menu of various flowers š¼ for user to choose from and this is how we write that.
class Multiple extends React.Component {
state = {
flower: ""
}
letsChange = (event) => {
this.setState({ flower: event.target.value })
}
render() {
return (
<label>
Your Favourite Flower: šø
<select value={this.state.flower} onChange={this.letsChange}>
<option value="rose">Rose š¹</option>
<option value="sunflower">Sunflower š»</option>
<option value="tulip">Tulip š·</option>
<option value="hibiscus">Hibiscus šŗ</option>
</select>
</label>
)
}
}
In above example, if you try putting any of the four values that we gave in option in place of flower
inside state then you'll see the default item selected will be that flower. You can manipulate the selection from letsChange
function as well.
P.S.: There's this file input tag whose value is only read-only, š so it is by default an uncontrolled component in React. Further reading on this, is mentioned below. Rest assured, you're good to go. š
Instead of conclusion, I thought to give y'all some resources that I found helpful during writing this post, I'm sure they'll help you some way or the other. š