Hooked on React Redux: Get your feet wet with this simple app
Tags: react, redux, hackbrightacademy, frontend
Published: 2020-11-04 21:08:21

---
title: Hooked on React Redux: Get your feet wet with this simple app
published: true
date: 2020-10-21 08:08:13 UTC
tags: react,redux,hackbrightacademy,frontend,
canonical_url: 
---

Redux can be intimidating and has a reputation for being hard to implement at first, but it doesn’t have to be! This simple example can help you navigate the murky waters, avoid pitfalls, and get started with Redux!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oe2wxl978fazq9gj3t3r.png)

There’s a nice selection of options out there for managing state in React, and the solution you choose will be based on a number of factors (for example, the size and complexity of your application). This article focuses on a very specific use case and allows you to get your feet wet by refactoring a simple application to include Redux.

There’s a lot to learn from taking a fully functional application and purposefully breaking it in order to improve and grow. I gave a Lightning talk on Redux while at Hackbright Academy, and decided to refactor a short and sweet (well, maybe not so sweet 😳) app we used in a lab, called Sharkwords. The app is a hangman-style game that results in the character’s early demise if the secret word is not selected in under five guesses. Watch out for sharks…

### Step 1. Gather Your State and Set Up Your Store

In Redux, the `createStore` function creates an object, the “store,” that holds the application state for the entire app. It’s possible to shove every piece of state in there, but it’s not absolutely necessary (if you prefer, you can manage state that’s local to a component with the `useState` hook instead). In this example, we store the following state in the store:

- `numWrong` (i.e. the number of incorrect guesses)
- `guessedLetters` (i.e. which letters of the alphabet have been guessed)
- `word` (secret word hardcoded to “hello” for this simple example)

First, declare your initial state when starting a fresh game and create your store:

```javascript
const { Provider, useSelector, useDispatch } = ReactRedux;

const initialState = {
  numWrong: 0,
  guessedLetters: [],
  word: 'hello',
};

...

// Create a Redux store holding the state of your app.

const store = Redux.createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

// Wrap in <Provider> tags to access the store throughout the app

ReactDOM.render(
  <Provider store={store}>
    <Sharkwords />
  </Provider>,
  document.querySelector('#root')
);
```

### Step 2. Let’s See Some Action(s)!

It’s important to remember that the store is **immutable** , meaning it can’t be changed directly. So when the state changes in the app, a new state object is created (i.e., a copy is made with the minor change in it). To achieve these changes—for example when a user guesses a letter—we use **actions** and **reducers** (don’t worry, I’ll explain that in a bit). So let’s go ahead and declare two actions in our game:

```javascript
...

const GUESS_LETTER = 'GUESS_LETTER';
const RESET = 'RESET';

...
```

Pretty straightforward: the user can guess a letter, `GUESS LETTER`, or reset the game, `RESET`.

### Step 3. Setting Up Our Hooks… Line, and Sinker!

The store has a few helper methods that make using Redux super predictable and simple to use, but we’ll focus on two Redux hooks that do a lot of the heavy lifting: `useDispatch` and `useSelector`.

The store gets information to update state from these actions, and each action has: a ‘type’ property (this is the type of action and is _required_) and the payload (this is the info being sent to the store and is _optional_). For example, when a user clicks on a letter to submit a guess, we send this information (the action) to the store using the dispatch function returned by the `useDispatch` hook:

```javascript
const dispatch = useDispatch();

...

const handleClick = () => {
      // The dispatch function sends an action w/ a payload (letter) to the store

      dispatch({
        type: GUESS_LETTER,
        payload: letter,
      });
    };

...
```

We also need to select the part of the state we’re interested in. We’ll purpose the useSelector hook to achieve this:

```javascript
  const guessedLetters = useSelector(state => state.guessedLetters);
  const numWrong = useSelector(state => state.numWrong);
  const word = useSelector(state => state.word);
```

So, when the user selects the letter `a`, an action of type `GUESS LETTER` is dispatched to the store with the payload of string `a`.

Oh no, that wasn’t a correct guess. Our swimmer looks concerned. 😐

![](https://cdn-images-1.medium.com/max/1024/1*R_Odld9wZZgqfBYfCzfa1w.png)

### Step 4. For Every Action, There Is a Reaction 🦈

Now we need to hook into our store and provide the instructions on how the state should be updated for each type of action. We need to give our application the instructions it needs to _react_ to the specific types of actions, a kind of recipe. This is where the **reducer** comes in: just like it sounds, the reducer is a function that takes in multiple parameters and returns a single value. Let’s see how this works in Sharkwords:

```javascript
function reducer(state = initialState, action) {
// Check to see if the reducer cares about this action.

  switch (action.type) {
    case GUESS_LETTER: {
      const letter = action.payload;
      const correct = state.word.includes(letter);
      
      return {
        ...state,
        guessedLetters: [...state.guessedLetters, letter],
        numWrong: state.numWrong + (correct ? 0 : 1),
      };
    }
      
    case RESET: {
      return initialState;
    }
    
    // Otherwise, return the existing state unchanged.
    default:
      return state;
  }
}
```

First, we check to see if the action type matches the action types handled by the reducer function. If it does, we provide the logic to update state (`guessedLetters` and `numWrong`) depending on if the payload (`guessed letter`) is a correct or incorrect guess. The reducer returns the updated (copy) of the state or the unchanged state and React updates our components!

After four wrong guesses, our swimmer is understandably freaking out! 😱

![](https://cdn-images-1.medium.com/max/1024/1*6f7DJmVH8Tt2v2chBQ6mJw.png)

Alas, after one more wrong guess, we’ve reached five wrong guesses and we get the bad news that we’ve lost the game. Drats! We’re then prompted to play again. The `RESET` action is dispatched to the store, and the initial state is restored.

You can see all of Sharkwords on [GitHub](https://github.com/nicolleromero/sharkwords-redux). As a bonus, be sure to check out the Redux DevTools that support time travel ⏱ and hot reloading🔥! 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7yn5n6jfht1tcko5so7o.gif)

(Special thanks to [Hackbright Academy](https://medium.com/u/b936d5412331) for allowing me to repurpose their app for this article.)

**_About the author:_**

_Hi! 👋 Nicolle, here. I’m a Frontend Software Engineer that loves building in React. I’m looking for an awesome team to join, so please_ [_reach out_](https://www.linkedin.com/in/nicolle-romero/) _if you’re looking to hire a 🧨 engineer!_

* * *