Components are small, isolated and reusable units of work that make up a piece of a user interface. Each component is independent, with emphasis in separation of concerns, having it's own business & presentation logic.
In this post, I am going to show you how to create a single component, as well as how to mutate state within that component by either passing variables, one way in the component or by changing an input value which changes the component's state.
Code outlined in this article can be found on GitHub.
In the previous post, I showed you how to create a Hello World application with React. But this was just a simple example to get you started, as you getting to know React you might be getting eager to learn more of its goodies.
Such goodies are the React components. These are reusable units of work that make up the user interface. When you are designing your UI you do this unconsciously, you define small parts in the UI, which make it up as a whole. For example, think of a UI with a header, a body, a sidebar and a footer. You have 4 components here, each of them independent of the view that is composing them, each one of them can be reused in other views. The good part is that each of them is written once! Score!
React components can be defined via a function or an ES6 class. In latter case, it should derive from
Components follow a naming convention, a component must always start with a capital letter. React treats components that start with lowercase letter as DOM tags.
I start where I left in the previous post, so I will continue with the same setup for my React application. I am only going to add a new
app.js file and modify a bit the
main.js to use the App component, rather have everything defined there.
I import the App component in
main.js and I use it in
render method. The
message string is passed in the App component by using the
message custom attribute. This is passed in the
props object of the component, so the props for App component will be:
This is the full code for
Next up, I work out the
app.js file, in which I export the
App component. This is an ES6 class, and it derives from
React.Component. This exposes the
render method, so you must implement it in your component definitions. This method should return a valid
Let's dig some more into the render method. Following is its implementation, as you might see, it only returns valid JSX. I render the message in the jumbotron, then in next row is a form definition, with only one text input. After that, is another bootstrap row which uses the functional
SayHi component. Take a look at the code coming up and I will take it from there to discuss its bits and pieces.
The message that is rendered in the bootstrap jumbotron, is coming from the entry point,
main.js. I directly access the
message property from the
props object. This object is passed in the component's constructor.
Now on the
input element. I would like to change the value stored in the component when changing the input's content. Remember that each component has its own state, so it makes sense to store the input's value to the component's state and change it when user enters some text into it. For this reason, I am using the
state object of the component, this is inherited from the
React.Component class and it's a plain object property. I store a new entry, called
value and I pass it on the
value attribute of the
In order to change this
value property on the state, I use the
onChange handler, passing as callback the private
onNameChange method. So now, each time user is changing the input content, this handler will update the
state.value with the appropriate text.
Finally, I use a functional component to display the
SayHi is just a private function within the
App component. This function takes a
props object in the same fashion as the App component receives props parameter via its constructor.
You might be wondering, where is that
props property coming from? Answer is via the constructor parameters, this is common for all components. I have also initialized the
state object, with an object initializer and an empty
value property. Lastly, I made sure to bind the
onNameChange method to this class, so the
this used within that method has the scope of the App class. Make sure to call
super() if you are using a constructor, as this is mandatory in such case.
At the beginning of this blog, I talked about class and functional components. An example of class component is the
App and of functional is the
SayHi function. This function receives as well a props object, just like App component. React treats this is as standard component. It should return a valid JSX element. I return an
h4 element with the value passed or a message which prompts to enter a name if nothing passed or at least not 3 characters are entered.
Last piece in the puzzle, is the callback handler for the
onChange event. It only sets the state to the current text rendered in input element.
A rule that you should never forget is that you should not modify state directly, rather you should use the
setState(...) method when you'd like to update a state property. The only place that you can assign values to state directly is the constructor.
This is the full code of the
This is a very good step towards learning React, as you probably got the feel of what is a component and what a component can do. Unfortunately, this solution here is not scalable. My view definition contains too much markup, this can be divided further into components, which could broadcast/listen to state changes through some sort of communication mechanism.
In the next post, I am going to refactor this very simple application by separating the concerns into components and by building a communication mechanism between them so one component's state changes would affect another, independent component.
In this post you learned what a component is and how it is defined in React.
You have also learned how to create your own components, pass props to them and also mutate the component's internal state.
If you liked this blog post and found it useful, please like, share & subscribe for more! Also, if not yet a follower, follow me on Twitter!
This post is part of the Learning React series