React: A simple start

Andrew Bone - Jul 10 '20 - - Dev Community

Recently I've been learning react, I'm by no means an expert but I enjoy teaching as I learn. It's a great way to help people learn, cement what I've learnt and also get some feedback on what I may not have understood. As I'm still a learner I'll be converting an old project of mine over to react, the project I've chosen is material design switches.

The aim is to be able to just write a single HTML tag and get a simple, nice and accessible toggle switch back. I'll be using JSFiddle to show the various steps.

<MaterialSwitch>Toggle switch</MaterialSwitch>
Enter fullscreen mode Exit fullscreen mode

example

Setup

First things first, let's make a quick hello world!. I know we can use a react functional component rather than a full class while we're at this simple stage but we'll be needing to use a class later, to get access to states, so let's start with one.

The class needs to extend React.Component and just needs the render() function. Here it is.


ReactDOM.render(<MaterialSwitch />, document.querySelector("body"))
Enter fullscreen mode Exit fullscreen mode

You'll notice I have this line at the end for this demo we can pretend it's the same as having <MaterialSwitch /> in the html.

Create

Now let's actually think about the component we want to create, it's a checkbox so we need;

  • Label text child - text to appear next to checkbox
  • readOnly property - is the checkbox readOnly?
  • disabled property - is the checkbox disabled?
  • defaultChecked property - checked state on load
  • checked state - internal checked state

I think that's all we will need, I've got 3 different labels child, property and state. Both children and properties are passed in from a higher level and the component does not have any control over them, they simply exist. States however can be changed from within a component and are the beauty of React.

Adding State and Props

Because we want to use states we're going to need to use the constructor function. When you use the construction function you need to be sure to pass props to the super function in order to keep things working right.

constructor(props) {
  /**
   * This is the super function it ensures
   * the constructor function still carries
   * out it's original purpose.
  */
  super(props);

  /*
   * Here I am setting up the default states
   * I am setting "checked" to be equal to 
   * the property "defaultChecked"
  */
  this.state = {
    checked: props.defaultChecked
  }
}
Enter fullscreen mode Exit fullscreen mode

We're also going to want to copy in our HTML from the existing project but with a few React changes.

render() {
  // This is how get our props, we could have
  // done this.props.readonly for each place
  // we wanted to use the props but I think 
  // this is easier to understand
  const {children, readonly, disabled, defaultChecked } = this.props;
  return (
    <label className="md_switch">
      <input 
        readonly={readonly}
        disabled={disabled}
        defaultChecked={defaultChecked}
        type="checkbox" 
      />
      <span className="md_switch__toggle"></span>
      {children}
    </label>
  )
}
Enter fullscreen mode Exit fullscreen mode

Anywhere you want to use a variable in the HTML, well JSX techically, just place the variable name inside some braces like so {variable}.

It's also worth pointing out, anywhere where you might want to add a class to your element you'll have to use className rather than the standard class this is because class is a reserved word in javascript.

Adding functions

All we need from our function is for it to update the state when the checked attribute of the checkbox changes. The function will be easy enough to write but there are another couple of things we'll need to do to get it all working.

/**
 * Update checked on change
 *
 * @param {Event} event - from the changed element
*/
changeHandler(event) {
  this.setState({checked: event.target.checked})
}
Enter fullscreen mode Exit fullscreen mode

Simple enough, set the checked state to the target of the event's checked param. Now let's link it up to the HTML/JSX.

render() {
  const {children, readonly, disabled, defaultChecked } = this.props;
  return (
    <label class="md_switch">
      <input 
        readonly={readonly}
        disabled={disabled}
        defaultChecked={defaultChecked}
        onChange={this.changeHandler}
        type="checkbox" 
      />
      <span class="md_switch__toggle"></span>
      {children}
    </label>
  )
}
Enter fullscreen mode Exit fullscreen mode

To add a function to the event you just need to add the onEvent tag, we want to trigger on change so we'll use onChange (notice the camelCase).

This still won't work though as within this.changeHandler the context of this has been changed to the event. To ensure the context of this remains bound to our react component we need to add the following line to our constructor function.

this.changeHandler = this.changeHandler.bind(this);
Enter fullscreen mode Exit fullscreen mode

Events

For the last bit of JS we're going to want to allow users of our component to use events, so we'll pass our events back up using props. As we're already using the onChange event we'll need to modify our function to sent the event up further.

/**
 * Update checked on change
 *
 * @param {string} text
*/
changeHandler(event) {
  const { onChange } = this.props;
  this.setState({checked: event.target.checked});

  If(typeof onChange === "function") onChange(event);
}
Enter fullscreen mode Exit fullscreen mode

I get onChange from props and now we can pass the event up. I've added the typeof function just in case the user adds something strange or even nothing at all.

The HTML/JSX bit is a lot easier we just need to pass our prop on like so

render() {
  const {children, readonly, disabled, defaultChecked, onInput } = this.props;
  return (
    <label class="md_switch">
      <input 
        readonly={readonly}
        disabled={disabled}
        defaultChecked={defaultChecked}
        onChange={this.changeHandler}
        onInput={onInput}
        type="checkbox" 
      />
      <span class="md_switch__toggle"></span>
      {children}
    </label>
  )
}
Enter fullscreen mode Exit fullscreen mode

Styling

Styling is as simple as adding our CSS I won't go over the CSS as it's exactly the same as the original post I was recreating. So here it is.

Wrapping up

Well there we have it, we have made our first react component. We have a simple tag that can used to input a material toggle.

Let's look at the HTML and the final result.

<div>
  <MaterialSwitch>Toggle Switch</MaterialSwitch>
  <br />
  <MaterialSwitch defaultChecked>Pre-activated</MaterialSwitch>
  <br />
  <MaterialSwitch disabled>Disabled</MaterialSwitch>
  <br />
  <MaterialSwitch defaultChecked disabled>
    Activated and disabled
  </MaterialSwitch>
  <br />
  <MaterialSwitch>
    Really really really long label
    content to hopefully span several lines
    to show that the checkbox will stay central.
  </MaterialSwitch>
</div>
Enter fullscreen mode Exit fullscreen mode

And that's it, we're home free, thanks for reading. If you have any questions, suggestions or just wanna chat feel free to comment down below. Thanks again!

🦄🧠💕🦄🦄💕❤🧠💕❤

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .