Start Using Redux Hooks in Your Projects
Tags: redux, javascript, react, reactnative
Published: 2020-02-22 21:23:22

Redux hooks have been around for quite some time now so why aren't you using them in your projects? Maybe you're just too attached to `connect()`, `mapStateToProps` and `mapDispatchToProps`. Maybe you just haven't taken the time to research the Redux hooks and how to utilize them in your projects. Or maybe, you just find them to be a little bit confusing. 

Don't worry because I too was just a little too comfortable with using the standard methods for Redux. But once I decided to jump in and actually implement the Redux hooks, I haven't looked back. 

I'll help walk you through some examples of how you can replace `mapStateToProps` and `mapDispatchToProps` with the easy to use `useSelector` and `useDispatch` hooks.

Let's take a look: 

```javascript
// ../reducers/ui.js

import * as types from '../actions/types'

export const ui = (state=initialState, {type, payload}) => {
    switch (type) {
        case types.SET_EXERCISE_VISIBILTY:
            console.log('action', payload)
            return {
                exerciseModal: payload
            }
        default:
            return state
    }
}

const initialState = {
    exerciseModal: false
}

// ../reducers/exercises.js

import * as types from '../actions/types'
import { exercises as initialState } from '../initialState.js'

export const exercises = (state=initialState, {type, payload}) => {
    switch (type) {
        case types.FILTER_EXERCISES:
            console.log(payload)
            const newArray = initialState.filter(item => item.name.toLowerCase().includes(payload.toLowerCase()))
            return [...newArray]
            break;
        default:
            break;
    }
    return state
}

// ../reducers/index.js

import { ui } from './ui.js'
import { exercises } from './exercises.js'
import { combineReducers } from 'redux'

export default combineReducers({
    exercises,
    ui
})

// ../store/store.js

import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from '../reducers'

export const store = createStore(rootReducer, applyMiddleware(thunk))

```

What I did here was created two separate reducer files. I imported them all into a single file, `../reducers/index.js` and utilized the Redux hook `combineReducers` to combine them into a single root reducer.

In the `../store/store.js` file, I went ahead and created our Redux store with my root reducer and the `thunk` [middleware](https://www.npmjs.com/package/redux-thunk) to allow me to perform my dispatches asynchronously. 

Now let's create our actions: 

```javascript

// ../actions/types.js

export const SET_EXERCISE_VISIBILTY = 'SET_EXERCISE_VISIBILTY'
export const FILTER_EXERCISES = 'FILTER_EXERCISES'

// ../actions/actions.js

import * as types from './types.js'

export const setExerciseModalVisibilty = (visible) => dispatch =>  {
    dispatch({type: types.SET_EXERCISE_VISIBILTY, payload: visible})
}

export const filterExercises = (filter) => dispatch => {
    console.log(filter)
    dispatch({type: types.FILTER_EXERCISES, payload: filter})
}
```

Here I created two separate files, one to store our actions and the other to store our types. 

Now that we have those set up we can head on over to our `index.js` file to set up our Provider

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
import { Provider } from 'react-redux';
import { store } from './store/store.js'

ReactDOM.render(
<Provider store={store}>
    <App />
</Provider>
, document.getElementById('root'));

``` 

Alright, let's start using our reducers inside of our components now. 

I'll show you how it would look utilizing `mapStateToProps`, `mapDispatchToProps` and `connect` before refactoring it to utilize `useSelector` and `useDispatch`

```javascript

// using mapStateToProps and connect

import React from 'react'
import { TopBar } from './TopBar.js'
import { setExerciseModalVisibilty } from '../actions/actions'
import { connect } from 'react-redux'

const CurrentWorkout = (props) => {
    return(
        <>
            <TopBar style={styles.topBar}>
                <h2>
                    Current Workout
                </h2>
            </TopBar>
            <div>
                <p>
                    add some exercises
                </p>
                <button onClick={() => props.setExerciseVisibilityModal(!props.visible)}>
                        +
                </button>
            </div>
            {props.visible && props.exercises.map(exercise => (<h3>{exercise.name}</h3>))}
        </>
    )
}

const mapStateToProps = ({ui, exercises}) => {
   return {
      visible: ui.exerciseModal,
      exercises: exercises
 }
}

const mapDispatchToProps = {
  setExerciseModalVisibility
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CurrentWorkout)


// using Redux hooks

import React from 'react'
import { TopBar } from './TopBar.js'
import { setExerciseModalVisibilty } from '../actions/actions'
import { useDispatch, useSelector } from 'react-redux'

const CurrentWorkout = (props) => {
    const [visible, exercises] = useSelector(({ui, exercise}) => [ui.exerciseModal, exercises])
    const dispatch = useDispatch()
    
    return(
        <>
            <TopBar style={styles.topBar}>
                <h2>
                    Current Workout
                </h2>
            </TopBar>
            <div>
                <p>
                    add some exercises
                </p>
                <button onClick={() => dispatch(setExerciseModalVisibilty(!visible))}>
                        +
                </button>
            </div>
            {visible && exercises.map(exercise => (<h3>{exercise.name}</h3>))}
        </>
    )
}

export default CurrentWorkout
```

As you can see, by utilizing `useSelector` we can return an array with our wanted state directly inside of our component. 

Similarly, we can use `useDispatch` to create a reference to our dispatch functions inside of our Redux store. We can then pass our action inside of that dispatch reference. 

Next time, I'll show you how you can implement the Redux Toolkit into your projects.

For a deeper dive into Redux hooks, be sure to check out the official docs [here](https://react-redux.js.org/api/hooks)