React Context API: Three Way Light Switch

In the Way Too Simple Context API example, we made a simple light switch. This post will show why flux, the single source of truth, and Context API are really useful.

The last post had just two components (not counting the App component): a light switch and light bulb. Here we are going to add a second light switch making this circuit mimic the three-way switch common in many homes.

In this system we want the following to happen:

  • flipping any switch will change the state of the light
  • the “physical” direction of the switch shouldn’t matter

This is meant to represent a switch in real life, and physical switches don’t throw themselves in response to a change in the system. On a web app, you’d most likely want the component’s feedback to change to reflect the state of the app. If you are curious about how three-way switches work in electrical circuits, it’s quite interesting. Unlike the electric circuit, our mini React app has a single source of truth and by manipulating that we can affect the whole system.

Luckily, because of the way we designed the original Context API light switch app, adding another switch is easy enough as putting a second light switch in the App.js file in the three-way-switch branch of the Context API example project.

app.js 📄
import LightCircuit from './context/context'

class App extends Component {
  constructor(props){
    super(props)
    this.state = {on: false}
  }

  render() {
    return (
       this.setState({on: !this.state.on })
        } }>
        
); } } export default App;

We also added a few aesthetic things: the three-way class to remove the “on” / “off” label and another spacer, but to make this work, all that was added was just another LightSwitch component!

The magic is in the flipSwitch: () => this.setState({on: !this.state.on }) function in the Provider that gets passed to the LightSwitch component and run when someone clicks on the component. The flipSwitch function also looks at the App component’s state for the on property, negates it, and then sets it as the negated value creating a toggling effect.

Once again, since this is a simple example, we could accomplish this by lifting up the state and sending it back down with props, but with Context API it doesn’t need that direct chain. LightSwitch can place it in other components (like a Room, LightPlate, etc.) as long as they are children of the Provider.