Easy Step Control using React Hooks

Easy Step Control using React Hooks

Many Thanks to Revel and Donavon West!

Who am I

Hello, my name is Revel. I'm a ten-year-old who loves coding. Mostly I code in React.

In this article, I will talk about an Open Source npm package that I recently published called react-hooks-helper. It is a custom React hooks library intended to be your "helper".

But before we get there, I'd like to take you on a brief journey of my coding life.

My coding journey

When I was little, all I wanted to do was play with my dad. But when he couldn't play because he needed to work, I would sit upstairs in the attic where he had his office, and watch him code. I became interested in what he was doing.

As I grew older, I started to pick up on things. I was an inquisitive kid, so I started asking my dad A LOT of questions about coding.

My dad, Donavon West (a.k.a. @donavon) works at American Express as a Developer Avocado 🥑. He's also the managing editor of their Technology Blog.

He does a lot of writing and public speaking, so naturally, I wanted to do it as well. It's my dad who really got me interested in programing.

Here is a quick overview of some of the languages that I've learned.

Scratch

With the Scratch, you can create interactive games, stories, music, animations, and more! –> The Scratch team

Scratch Code

Scratch is one of the first languages I learned. It's easy and simple. and has a block based GUI. You drag the blocks into place and they snap together to form the steps of your program.

It's a fun language to learn, but not that powerful and kind of "kid-ish". When I was little I loved and praised the language, mostly because that was the only thing I could code in.

Python

Python is powerful... and fast; plays well with others; runs everywhere; is friendly & easy to learn; is Open. –> The Python Team

import time

print('Press ENTER to begin, Press Ctrl + C to stop')
while True:
    try:
        input()
        starttime = time.time()
        print('Started')
        while True:
            print('Time Elapsed: ', round(time.time() - starttime, 0), 'secs', end="\r")
            time.sleep(1)
    except KeyboardInterrupt:
        print('Stopped')
        endtime = time.time()
        print('Total Time:', round(endtime - starttime, 2),'secs')
        break

Python is a simple program for coding. Python is the second language I learned. It did more than Scratch. But I wanted to code web pages!

JavaScript

Then I saw that Dad was coding in something called "JavaScript"???? with "React"???? And I wanted to do that, too. Dad told me that before I could learn React, I had better know basic HTML, CSS, JavaScript, so he introduced me to Codepen.

After a lot of playing around with HTML, CSS, and JS, Dad finally told me I was ready to learn React. CodeSandbox was the first thing I used with React. It's an online editor/IDE. I love it so much that now I use it every day!

Finally… Let's talk React Hooks!

react-hooks-helper

Now that you know who I am and where I came from, I'd like to tell you about how I used React Hooks for my first Open Source package called react-hooks-helper, available on GitHub. react-hooks-helper is a very easy to use npm package which has a collection of many pre-made custom Hooks that do several useful things including handling step and form data. I've done all of the hard work for you! All of these hooks are based off of something I wanted to be easier and more straightforward. It seemed like React was plotting against me because everything seemed so hard until I made these Hooks.😉

react-hooks-helper contains several Hooks but for this article I will talk mostly about the Hook called useStep.

I've always wanted to make a Photo Carousel for my website (NOT done yet). It's hard to get the setInterval() working just right, so I made a custom Hook called useStep. useStep is a stepping wizard. It's a lot like React Albus if you're familiar.

useStep works by returning an object containing information on the current "step" and a set of navigation callback functions.

Installation

Hooks are currently at an RFC stage, and in React v16.8.0-alpha, (but soon will be out in the stable version!!), so you need to run: $ npm i react @next

You install react-hooks-helper as follows.

    $ npm i react-hooks-helper

And here's a brief description of the API.

    const { isPaused, index, step, navigation } = useStep(config);

You pass a config object to useStep. What is returned is an object with isPaused, index, step, and navigation.

Here are the options for the configuration object (* = required).

Key Description steps* Either an array containing the steps to process or an integer specifying the number of steps. initialStep The starting step—either a string id or an index. Default = 0. autoAdvanceDuration If you wish the steps to auto-advance, specify the number of milliseconds. You can also include an autoAdvanceDuration in each step in your steps array, if you wish to have different durations for each step.

Here is what is returned from useStep.

Key Description index A number containing the current step index. step The current step object from the steps array. navigation A navigation object (see below). isPaused``true if the autoAdvanceDuration is paused. autoAdvanceDuration Duration of the current auto-advance.

The navigation object returned from useStep contains control callback functions as follows.

Key Description previous Call to navigate to the previous item index. Wraps from the first item to the last item. next Call to navigate to the next item index. Wraps from the last item to the first item. go Call to navigate to a specific step by id or by index. Example: go(2) or go('billing-address')``pause Pause auto-advance navigation. play Play auto-advance navigation once it has been paused.

Now that you have a background on how useStep works, let's use it to write our carousel.

First, we'll need a list of images, something like this.

    const images = ['http://...'];

By the way, a lot of articles say "http://..." but don't give you image links. Go to [this link][0] to get an array of the images I used.

Then we'll start by writing the `Carousel` component. It takes the list of images and an initial step, all passed as `props`.

    const Carousel = ({ initialStep = 0, images }) => {
        // our code here
    );

We can take these props and pass them directly to useStep. For now we'll hard code an autoAdvance duration of 5 seconds, but we could have just as easily passed this in with props.

    const { step, navigation, index, isPaused, autoAdvanceDuration } = useStep({
      initialStep,
      autoAdvanceDuration: 5000,
      steps: images,
    });

In each render, step will contain the current item from the images array. We destructure it to obtain the description, the image src URL, and the alt text.

    const { description = '', src, alt = '' } = step;

Next all we have to do is render the image returned by useStep.

    return (
      <div className="carousel">
        <img alt={alt} src={src} />
        <div className="description">{description}</div>
        <Navigation isPaused={isPaused} index={index} count={images.length} {...navigation} />
        {!isPaused && <Progress step={index} duration={autoAdvanceDuration} />}
      </div>
    );

You may be wondering what: <Navigation /> is. It's the controls that we're rendering for moving the images around manually. Notice that we are spreading the navigation object as props to the Navigation control. These consist of previous, next, go, pause, and play.

The dots in the lower left are so you can directly navigate to any photo. For that were calling go and passing it the the image index.

Then down at the bottom right corner there's a play/pause button and a next/previous too. The play/pause button is for playing and pausing the carousel. It uses pause and play callback functions.


A really simple example

I'll explain the whole thing. Really fast. Right here. Right now. Ohhh yeah. 😆

    function App() {
      const {
        index,
        navigation: { previous, next },
      } = useStep({ steps: 3 });
      return (
        <div>
          {index === 0 && <div>This is step 1</div>}
          {index === 1 && <div>This is step 2</div>}
          {index === 2 && <div>This is step 3</div>}
          <div>
            <button disabled={index === 0} onClick={previous}>
              Previous
            </button>
            <button disabled={index === 2} onClick={next}>
              Next
            </button>
          </div>
        </div>
      );
    }

We call useStep with the number of steps that we would like. We then destructure the response to get the current index and the navigational callback functions previous and next.

Then App is rendering the text for the different steps. Only one step will render as we are using a logical AND statement. These could just as easily be have components that render entire pages.

Then we render the navigation buttons, passing the callback as the onClick handler.

This is the final output. Try it. It's interactive:


Another thing to do

Here is a more complicated example that was written using useStep. It also uses useForm, one of the other "helpers" in react-hooks-helper. useForm abstracts away much of the boilerplate needed to handle form data. You can find more about it in my README on GitHub.

Conclusion

Through my journey of coding I finally came across React. Then I wrote an open source npm package called react-hooks-helper.

react-hooks-helper is a React custom Hook library with:

We talked about useStep in this article and explained that useStep can be used to make mulit-step forms and carousels.

useStep is a Hook for stepping. And if you don't think that, read the article again!

I hope you enjoyed this article and will find uses for useStep and useForm. Please give it a try.

About me

Also I'm @revelcw for everything:

Note:not in that order 😉

I also told the story of My Coding Journey back in December of 2017 at React NYC. You can watch it here.

Acknowledgments

I'd like to thank the following people:

The contributors to JavaScript January are passionate engineers, designers and teachers. Emily Freeman is a developer advocate at Kickbox and curates the articles for JavaScript January.