Managing state and forms with React. Part 1
Simple form example
We will start with the really basic example. React component to add new user.
To keep an example simple we’ll hold all the data in the component’s local state, and assume that the component will make the direct HTTP request to the server on form’s submit to save the results. Like this:
First, we will add some markup to create the dummy form:
We’re using React’s controlled components here with an internal state which is bound to the values from the local component’s state. Thus, to make this form work, we heed to add onChange event handlers to modify the state on user’s input event. Otherwise form will be read-only. Like this:
Now, our basic form should works, but you can see some repetitive pattern in the code which doesn’t look too elegant even in such a simple example. We are going to investigate ways to make React forms look much better than that.
Introducing Value Links pattern
Obvious idea would be to hide that value/onChange props binding behind some custom <input/> component wrapper. But how?
Ideally, we would like just to pass the single state value to our <TextInput/> in the way that component could modify it. Which can be done if we wrap our value to an object holding both the value and the function to update it.
Which, essentially, is called “Value Link”. We could create links with a functions like this one, which needs to be written once:
And then, use it like this:
With such a thingy, our custom <Input/> component become simple and elegant:
Good thing about Value Link pattern is that your custom input component doesn’t imply anything on how the application state is really managed. It could be React state. Or it could be something else, hidden behind valueLink.set( x ) function. <Input /> doesn’t care. All data-binding logic is being encapsulated in the particular value link object.
This feature of value links opens up a lot of opportunities which will be covered in the next articles.
As you can see, it’s fairly easy to make simple value links and input wrappers yourself. But this is probably not the thing you want to do. You might prefer doing npm install instead:
npm install valuelink --save-dev
Then, just import links and components which has been already prepared for you, extend LinkedComponent, and start writing the
render() right away:
Still, these this.linkAt() calls looks a bit clumsy adding some visual noise. Therefore, we will make our finishing stroke — use this.linkAll() helper provided by the ValueLink library.
this.linkAll() will create links for all state attributes (or for listed attributes if state keys were passed — like this.linkAll( ‘a’, ‘b’ )), and wrap them in the single object. With this change, our render() method finally becomes nice and clean:
Not only this code looks nice, but it also is pretty efficient. Thing is that ValueLink library is way smarter than our naive linkState function from the previous section. All the links to the state members it creates are being transparently cached inside of the component. They will be recreated only in case if their values will actually change.
linkAll() makes sure that all cached links are up to date, and gives you the direct access to the component’s links cache. Also, you can access links from your custom event handling methods with this.links; no need to recreate them there.
I don’t like these <Input /> wrappers!
Understandable. That’s probably because you didn’t read the next article about forms validation yet. It demonstrates how you can really benefit from them.
But anyway, there are some good news for you. You can use ValueLink with standard React form inputs, because the link can convert itself to the pair of value/onChange props. Just add .props:
That’s how the React’s two-way data binding looks like. Quite nice, isn’t it?
So, that’s how we’re handling simple forms. And it was really the beginning. Volicon Value Links provides you with a lot of advanced features such as easy form validation, and links to an elements of the complex component state.