Two React Switch components of different colors.

Learn how to build a React switch component using the native HTML checkbox input! You’ll learn plenty about React checkboxes in the process.

If there’s one UI component that iOS introduced to the world, it’s the switch or toggle as some people refer to it as.

What We’re Building

Long before iOS introduced the switch, the web’s boolean input was the trusty checkbox. Checkboxes are of course still used to this day, but the switch improved on the checkbox by emulating physical switches found in the real world.

A switch feels tangible. Clicking or tapping it feels like you’re actually using a real-life switch as opposed to clicking a checkbox.

Therefore, in this tutorial, we’re going to build a new React switch component that piggybacks on the native HTML checkbox input. And, using some CSS, we’re going to turn that simple, age-old checkbox into a snazzy looking switch!

Building the React Switch Element using HTML

Whenever I’m building a brand-new React component, I’ll always, always begin by scaffolding it out in HTML and CSS and when I’m happy with the look and feel, then I’ll move over to writing the JavaScript.

Create a new file called Switch.js and add the following code to it:

Switch.js
import React from 'react'; import './Switch.css'; const Switch = () => { return ( <> <input className="react-switch-checkbox" id={`react-switch-new`} type="checkbox" /> <label className="react-switch-label" htmlFor={`react-switch-new`} > <span className={`react-switch-button`} /> </label> </> ); }; export default Switch;

If you saved the component at this point, you’d see a simple checkbox. That’s because we use the checkbox input as the basis for our React switch component.

There’s no need for us to re-invent the wheel here. A switch is, after all, another way of representing a boolean value (true or false). The checkbox input is a native input to handle boolean values.

Styling our React Switch with CSS

Create a new file under the same directory as the component file, called Switch.css. Drop in the following CSS. Feel free to take a look at each class. I’m not going to explore the CSS in this tutorial as the focus is on JavaScript and React.

Switch.css
.react-switch-checkbox { height: 0; width: 0; visibility: hidden; } .react-switch-label { display: flex; align-items: center; justify-content: space-between; cursor: pointer; width: 100px; height: 50px; background: grey; border-radius: 100px; position: relative; transition: background-color .2s; } .react-switch-label .react-switch-button { content: ''; position: absolute; top: 2px; left: 2px; width: 45px; height: 45px; border-radius: 45px; transition: 0.2s; background: #fff; box-shadow: 0 0 2px 0 rgba(10, 10, 10, 0.29); } .react-switch-checkbox:checked + .react-switch-label .react-switch-button { left: calc(100% - 2px); transform: translateX(-100%); } .react-switch-label:active .react-switch-button { width: 60px; }

Using the React Switch Component

There’s one last step required in order for us to use the React switch component and that’s importing it into another component file and declaring it:

App.js
import React from 'react'; import Switch from "./Switch"; function App() { return ( <div className="app"> <Switch /> </div> ); } export default App;

Save the file, jump over to your browser and watch the simple checkbox input transform into a rather beautiful looking switch input!

Handling onChange and Passing a Value Through Props

Although our React switch may look like it’s functional, behind the scenes it’s not actually changing its value.

That’s because our switch’s checkbox input does not have two very important attributes. These are:

  • checked
  • onChange

The checked attribute stores the input’s current value. In our case, it would be true or false.

The onChange attribute is an event handler that triggers whenever the switch toggles. We’ll use this event handler to change the component’s current value.

Before we jump into some code, let’s talk about ‘stateless’ components and ‘stateful’ components. A stateless component, or ‘dumb’ component, is a component that does not control its own state. As a result, it requires another component to keep track of the React switch component’s state.

Our React switch component is going to be a stateless component. Therefore, it requires us to pass a value from a parent component through its props.

Open up Switch.js and modify it with the following:

Switch.js
import React from 'react'; const Switch = ({ isOn, handleToggle }) => { return ( <> <input checked={isOn} onChange={handleToggle} className="react-switch-checkbox" id={`react-switch-new`} type="checkbox" /> <label className="react-switch-label" htmlFor={`react-switch-new`} > <span className={`react-switch-button`} /> </label> </> ); }; export default Switch;

The code above makes four new additions:

  • isOn is passed in through props
  • handleToggle function is passed in through props
  • checked attribute is added, and uses the value from the isOn prop
  • onChange event handler is added and uses the handleToggle function prop

Finally, open up the parent component (I’m using App.js) and modify the React Switch component declaration to match the following code:

App.js
import React, { useState } from 'react'; import './App.css'; import Switch from "./Switch"; function App() { const [value, setValue] = useState(false); return ( <div className="app"> <Switch isOn={value} handleToggle={() => setValue(!value)} /> </div> ); } export default App;

Notice how this parent component now has state from using the useState Hook. That means that this component is going to pass down the state value into our React switch component’s isOn prop.

We also pass down the state setter function, setValue, into the handleToggle prop. As a result, when the Switch component is toggled and changes its value, it will call what is passed to the handleToggle prop.

Changing the Background Color onChange

If you saved the React switch component and toggled it in the UI, you’d see that there is no visual difference

…yet.

We only have to make one simple change to the React switch component in order to change the background color of the switch. That’s because we have access to the switch’s state through the isOn prop.

Modify the label HTML element inside Switch.js to the following code:

Switch.js
... <label style={{ background: isOn && '#06D6A0' }} className="react-switch-label" htmlFor={`react-switch-new`} > ...

Save the component, jump on over to your browser and you’ll see a fully working Switch component that lights up green when it’s turned on!

And there we have it! We’ve made a complete React Switch component that toggles, changes value, and lights up green when it’s on.

Read on if you want to learn how to expand our Switch’s functionality by specifying the on color.

Specifying the Switch Color

It’s good practice to build flexible React components so that they may be used in a variety of scenarios. For example, we might want to use a switch component:

  • In a sign-in form, as a way to tell the site to remember your user credentials
  • On a settings page
  • In a modal dialog for deleting a user account

Those are three examples, however, there are countless implementations for a switch.

Here’s the thing. Right now, our React Switch component only lights up green. What if we wanted it to light up red when we use it in that modal for deleting a user account?

Let’s add another prop to our switch component, called onColor:

Switch.js
import React from 'react'; const Switch = ({ isOn, handleToggle, onColor }) => { return ( <> <input checked={isOn} onChange={handleToggle} className="react-switch-checkbox" id={`react-switch-new`} type="checkbox" /> <label style={{ background: isOn && onColor }} className="react-switch-label" htmlFor={`react-switch-new`} > <span className={`react-switch-button`} /> </label> </> ); }; export default Switch;

onColor will be a string value representing a hex color. Save that. Jump over to the parent component and add the new onColor prop to the Switch declaration:

App.js
import React, { useState } from 'react'; import './App.css'; import Switch from "./Switch"; function App() { const [value, setValue] = useState(false); return ( <div className="app"> <Switch isOn={value} onColor="#EF476F" handleToggle={() => setValue(!value)} /> </div> ); } export default App;

Now we’ve got a flexible, modular React switch component!

Thanks for reading, and I really hope you enjoyed this tutorial. I write all of the tutorials on here, and I’m going to continue adding more and more tutorials each month.

If there’s a particular tutorial that you want to see, I want to hear from you! Contact me through the about page, even if you aren’t suggesting a tutorial — I’d love to hear from you just the same!

Avatar photo
👋 Hey, I'm James Dietrich
James Dietrich is an experienced web developer, educator, and founder of Upmostly.com, a platform offering JavaScript-focused web development tutorials. He's passionate about teaching and inspiring developers, with tutorials covering both frontend and backend development. In his free time, James contributes to the open-source community and champions collaboration for the growth of the web development ecosystem.

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.