How do you use checkboxes in React.js? We've learnt about radio buttons in this tutorial, but what about checkboxes - do you use them differently in React?
The short answer is: yes.
Let me demonstrate how to use checkboxes with the help of a simple React application:
You can find the full source code in this GitHub repository.
Our application is going to render a list of checkboxes with labels and a
Save button. We can toggle checkboxes and click
Save button. We will then see in the Developer Tools Console log messages that tell us which checkboxes were checked:
Our application will be made of two React components:
Application component is a container component - it encapsulates our entire React.js application, and renders three instances of
Checkbox component and a
Application component also logs into the Developer Tools Console which checkboxes were checked when users click the
Checkbox component renders a checkbox with a label.
Let's create our
Application component first:
First, let's focus on its
We see three
div elements with class names that you might recognize if you're familiar with Bootstrap. Bootstrap helps us create layout for our page.
Now let's focus on the
Inside of our
form element we call
this.createCheckboxes function that creates three instances of a
Checkbox component. We'll see how exactly it does that in a moment. It's important to recognise that here we're creating our instances of a
Checkbox component dynamically. If you're not familiar with this approach, then please read this tutorial first.
We then create a button element of type
submit which will submit our form when user clicks on it, we're telling React to call
this.handleFormSubmit function when this happens:
Let's take a look at how exactly we're creating our instances of
Checkbox component dynamically. Here is our
It iterates over
items array and calls
this.createCheckbox function for each item in that array. Where is
items array coming from and what is it for?
Application.js file before declaring our
Application component, we create
items constant that references an array of three items:
['One', 'Two', 'Three'] - these are labels for our checkboxes. This array represents data that will dictate how many checkboxes we need to render and what their labels will be. For the purpose of this tutorial, we declare this data in our React component file, but in a real world web application this data can be received from a server or imported from another file.
Now we know that
createCheckboxes function calls
this.createCheckbox function for each label in
createCheckboxes function also returns an array of three instances of
Checkbox component. That's because we call
this.createCheckbox three times and each time it creates and returns an individual 'Checkbox' component instance:
Checkbox component instance gets three properties:
label- the text that you see rendered next to a checkbox. This value is coming from our
handleCheckboxChange- a reference to
this.toggleCheckboxfunction. Every time user checks/unchecks a checkbox React calls
this.toggleCheckboxfunction. We'll see what it does in a moment.
key- as you already know, each dynamically created React component instance needs a
keyproperty that React uses to uniquely identify that instance.
Now we understand how we create and render three checkboxes in our application. What happens when user checks/unchecks our checkbox? As you will see later - every time user change checkbox's state - our
this.toggleCheckbox is called.
Let's take a look at that
It gets a
label parameter that represents which checkbox is being toggled. Now what exactly
toggleCheckbox function does with a
It's a good time to zoom out for a second and talk about how our application works. There are a couple of questions we need to ask:
Each checkbox has two states: checked and unchecked. Which React component is responsible for managing that state?
How do we know which checkboxes are checked at any given moment in time?
We want to keep our application as simple as possible, so a simple answer for our first question is: let each
Checkbox component instance maintain it's own state. Meaning: each
Checkbox component instance is responsible for managing it's own state and knowing when it's checked or unchecked.
That's the key point: our
Application component is not responsible for managing
Checkbox component instance state and hence it doesn't know anything about it. The advantage of this approach is that now our
Application component can create as many instances of a
Checkbox component as we need and it doesn't need to deal with managing the state of each
Checkbox instance. In addition this solution makes our
Checkbox component more reusable as it doesn't depend on a parent component.
This sounds fantastic, but coming back to our second question: how do we know which checkboxes are checked in our
Application component? This question highlights the disadvantage of our approach, because as I've mentioned earlier, our
Application component knows nothing about state of each instance of a
Luckily, there is no need for our
Application component to know the state of each instance of a
Checkbox component at any given time. All it needs to know is: which checkboxes are selected at any given time.
Should we store that information in
Application component's state? Should we make our
Application component stateful?
No. Remember in React you want to keep as little information in component's state as possible. And this should come naturally to you when you start thinking about it this way: does this information affects what my component is rendering? In other words, if that information changes - do I want React to rerender my component? If the answer is "no" - don't store it in component's state. If the answer is "yes", then that information represents your component's state and it should be stored in your component's state.
In the case of our
Application component - when user checks or unchecks any checkbox that we render - do we need to rerender our
Application component? The answer is clearly no. Therefore, we don't want to store a list of checked checkboxes in
Application component's state.
Ok, if not in the component's state, then where? In a property that we can set on the component's class.
Let's set a property on the component's class that will store information about which checkboxes are checked. The next question that we should ask ourselves is: which data structure should I choose for storing that information?
What are the requirements for our perfect data structure?
That sounds like a description of a data structure that you might know about: Set.
Now we know that we want to create a new Set and assign it to
Application's component specification object.
The next question we need to answer is: when should we create our empty Set? That will depend on whether we want our Set to be created before or after the
Application component is rendered.
The answer is: we want our Set to be created right before we mount our
If you're not familiar with
componentDidMount method or any other React component lifecycle methods, then please read this tutorial first.
this.selectedCheckboxes = new Set(); creates a new
selectedCheckboxes property on component specification object and assigns a new set to it.
Now we have an empty set created right before our
Application component is rendered. Then, when user checks/unchecks our checkboxes React will call
That function will reference our set and check if a specific checkbox label is in that set:
If the label is already in our set then we delete from the set:
Otherwise, we add it to our set:
And that's how our
Application component is going to know which checkboxes are checked at any given moment in time. If the label in the set - it's checked; if not - it's unchecked.
What happens when the user clicks
Save button? Our form is submitted and our
handleFormSubmit function is called by React:
Let's take a look at
First it prevents the default behavior of a form's submit event:
for... of statement to iterate through our
this.selectedCheckboxes set and log every item from that set. Which effectively prints the label of every checked checkbox.
Now you know how what our
Application component does and how it works.
Next let's take a look at our
Checkbox component is a stateful component because it needs to know whether a checkbox element should be rendered as checked or unchecked.
We'll use class property
state to set the initial state of our
The state of our component is represented by
isChecked property. By the default its value is set to
false because initially we want every checkbox to render as unchecked.
Let's see what our
Checkbox component renders:
div element with a Bootstrap class name that we use for styling. Inside of it we have
label element with two children: 1)
input element and 2) label text.
input element renders the checkbox. It has 4 properties:
type- the type of input:
checkboxin our case.
value- the value of input: which is a label name passed as property from a parent
checked- whether it's checked or not. The value comes from component's state property
this.toggleCheckboxChangefunction will be called when user checks or unchecks a checkbox.
The label text is coming from a property
label that is passed from a parent
Application component. It will be either
Now if you read this tutorial, you will recognise that our
input element is a controlled component because we "control" the
value property by providing our own value that comes from
this.props.label. If you're not sure about the difference between controlled components and uncontrolled components, then I recommend you read this tutorial.
What happens when the user toggles our checkbox?
this.toggleCheckboxChange function is called:
Checkbox component's state. It set's
isChecked's value to the opposite of it's current value and it calls
handleCheckboxChange function which is passed to
Checkbox component as a property by it's parent
This function call will trigger
toggleCheckbox function in
Application component that will add or delete the label name that we're passing as an argument via
this.props.label from the set.
That's how our
Application component will always know which checkboxes are selected at any given moment in time.
And now you know how to use checkboxes in React.js!
Notice that this solution works great for our specific needs. If you have different requirements you might need to think of a different way of creating checkboxes. For example, how do you implement a button that checks all checkboxes? I'll leave it for you to figure it out as a challenge! And if you do figure it out - please propose your tutorial for this website!
Thank you for reading this React tutorial!