How to build a React checkbox

Mathew Pregasen
Mathew Pregasen
Guest Writer

Dec 20, 2023

When you’re building with the popular front-end library React, leveraging reusable components can make your job much easier. Components like tables and navbars are pretty much essentials—and you can add the ever-useful React checkbox to that list.

What is a React checkbox?

The React checkbox is a React component that implements a checkbox—that is, a widget that either displays a checked (true) or unchecked (false) state. (There’s also first-class support for an indeterminate state in a checkbox.) Checkboxes, alongside switches, are ideal UI components for displaying a boolean state.

With React’s component-based architecture, it’s typical for developers to build a React checkbox component that can be imported across the application. In this article, we’ll discuss how to build a React checkbox, its basic structure, and how to customize it.

The benefits of using React checkboxes

In comparison to an ordinary HTML checkbox, a React checkbox is bound to a React state variable, which makes it easy to connect to the general logic of an application. Additionally, because mounting React components inside one another is made easy by the library, React checkboxes are very portable.

Independently, another benefit is that checkboxes are small and preserve space in the UI. They provide a clear indication of selected options. They may also automatically work with accessibility tools for blind or visually impaired users.

Working with checkboxes in React

Building a React checkbox component is quite straightforward, but still includes all the rudimentary parts of any React component. Let’s go through each of them.

useState Hook

React’s useState hook enables developers to initialize a React state variable within the component’s lifecycle. It also creates a function to safely set that variable. However, we will not include useState inside the React component—unlike Angular or Vue, React has an unidirectional data flow, so we’ll declare that outside of the component and pass it in as a prop. If we initialized the checkbox’s state from within the component, then the state would be inaccessible outside of it! That’s known as an uncontrolled element and isn’t ideal for this scenario.

1const Checkbox = (props) => {
2	return <></>
3}
4const App = () => {
5	const [val, setVal] = useState(false); //initializes checkbox to false 
6	return <>
7		<Checkbox value={val} setValue={setVal}></Checkbox>
8	</>
9}
10

This code sets the initial code value of the checkbox to false.

Of course, we could do this over two files and import the Checkbox into the App component—but for the sake of brevity, we’ll keep them in the same file!

Input element

HTML has a native input element with a checkbox type. We’ll build our React checkbox component around this native element, directly interfacing with the HTML element’s native properties.

1const Checkbox = (props) => {
2	return <input type="checkbox" checked={props.val}/>
3}
4const App = () => {
5	const [val, setVal] = useState(false); //initializes checkbox to false 
6	return <>
7		<Checkbox value={val} setValue={setVal}></Checkbox>
8	</>
9}
10

We’ll then use the general React event handler, onClick, to alter the checkbox’s state, executed after any clicks. Because checkbox’s only flip state, we can easily set the correct value by inverting the checkbox’s present value.

1const Checkbox = (props) => {
2	return <input type="checkbox" checked={props.val} onClick={() => {props.setValue(!props.val)}}/>
3}
4const App = () => {
5	const [val, setVal] = useState(false); //initializes checkbox to false 
6	return <>
7		<Checkbox value={val} setValue={setVal}></Checkbox>
8	</>
9}
10

The core benefit of this approach is it still uses HTML’s native checkbox input element, while simultaneously being apt for React applications.

onChange prop

There is an issue, however, with our current code. Sometimes, a user might change a checkbox’s value without clicking on it. Examples would be using the keyboard to focus on the checkbox and selecting it. Or, by using a screen reader.

Instead of using the onClick prop, we want to use the onChange prop to be more robust.

1const Checkbox = (props) => {
2	return <input type="checkbox" checked={props.val} onChange={() => {props.setValue(!props.val)}}/>
3}
4const App = () => {
5	const [val, setVal] = useState(false); //initializes checkbox to false 
6	return <>
7		<Checkbox value={val} setValue={setVal}></Checkbox>
8	</>
9}
10

Adding a checkbox label

Of course, a floating checkbox isn’t too much help to the user. They also need to know what they are checking and un-checking. That’s where a checkbox label comes in handy.

A label is not just a text box that describes the checkbox. It’s also a clickable surface that changes the checkbox value. We can use HTML’s native label element to easily accomplish this. We’ll also set the text inside the label by using a prop so that the value could be set by the parent component!

1const Checkbox = (props) => {
2	return <label>
3		<input type="checkbox" checked={props.val} onChange={() => {props.setValue(!props.val)}}/>
4		{props.label}
5	</label>
6}
7const App = () => {
8	const [val, setVal] = useState(false); //initializes checkbox to false 
9  const label = "My Checkbox!" 
10	return <>
11		<Checkbox value={val} setValue={setVal} label={label}></Checkbox>
12	</>
13}
14

Form elements

Sometimes, a checkbox might be deployed inside a form. If that’s the case, the checkbox needs a name so that it’s a named input inside of the form block. We can accomplish this by just making name another prop that is passed into the Checkbox component.

1const Checkbox = (props) => {
2	return <label>
3		<input type="checkbox" name={props.name} checked={props.val} onChange={() => {props.setValue(!props.val)}}/>
4		{props.label}
5	</label>
6}
7const App = () => {
8	const [val, setVal] = useState(false); //initializes checkbox to false 
9  const label = "My Checkbox!" 
10	return <>
11		<Checkbox value={val} setValue={setVal} label={label}></Checkbox>
12	</>
13}
14

Customizing the checkbox

Of course, almost all React apps are customized with personalized aesthetics. We can apply that same custom styling to our component. While this color scheme won’t necessarily match your application’s, it should illuminate how easy it is to add custom stylings.

Now, let’s break off Checkbox into its own file so that we can isolate our personalizations more cleanly.

1// checkbox.js
2import React from "react";
3import "./checkbox.css";
4
5const Checkbox = (props) => {
6  return (
7    <label className="checkbox">
8      <input
9        type="checkbox"
10        name={props.name}
11        checked={props.val}
12        onChange={() => {
13          props.setValue(!props.val);
14        }}
15      />
16      {props.label}
17    </label>
18  );
19};
20
21export default Checkbox;
22

Now we can create a CSS file that will be imported into our component.

1/* checkbox.css */
2
3label.checkbox {
4	color: #ddd;
5	display: flex;
6	align-items: center;
7	justify-content: left;
8    width: 300px;
9    gap: 4px;
10}
11
12label.checkbox > input {
13	outline: none;
14	height: 20px;
15	border-radius: 5px;
16}
17

Of course, these styles should follow how CSS is configured in an application as well as the application’s overall style guide.

We can now import that Checkbox into the original App.js.

1// App.js
2
3import React from "react";
4
5const App = () => {
6	const [val, setVal] = useState(false); //initializes checkbox to false 
7  const label = "My Checkbox!" 
8	return <>
9		<Checkbox value={val} setValue={setVal} label={label}></Checkbox>
10	</>
11}
12

Additional props

While a standardized checkbox is what’s in scope for today’s tutorial, there are additional optional props you could consider. These include:

  • The ability to personalize the checkbox color or choose between preset color themes
  • A boolean to gray out / disable the checkbox

Of course, it only makes sense to add these features if they are going to be actually invoked in the application.

Closing thoughts

In this article, we explored how to build a configurable and personalized React checkbox component. The component has a configurable label and can dynamically invoke a mutation function. With React’s component-based structure, the component can easily be reused throughout the application.

The best React component library is in Retool. Grab a checkbox component and get building.

Reader

Mathew Pregasen
Mathew Pregasen
Guest Writer
Dec 20, 2023
Copied