similar redux architecture example powered by react hooks API
Tags: react, redux, javascript, hooks
Published: 2019-01-06 15:12:00

---
title: similar redux architecture example powered by react hooks API
published: true
description: This is my discovery of how to use hooks, and make use of hooks. 
tags: React.js, Redux, javascript, hooks
---

I guess you guys have known hooks API already, haven't you? This article is one of the examples for React hooks API. First of all, here is the example code which I'm gonna describe it.
https://github.com/takahiro-saeki/react-example-code/tree/master/chapter2

and here is an example's screenshot.
![screenshot of example](https://thepracticaldev.s3.amazonaws.com/i/3ura92oa11b920lqwy2f.png "example")

Let's get started!

## Redux architecture with hooks API without Redux.

### architecture structure.
```
./chapter2
├── index.html
├── package.json
└── src
    ├── Context.jsx
    ├── Provider.jsx
    ├── actions
    │   └── index.js
    ├── components
    │   ├── Header
    │   │   ├── index.jsx
    │   │   └── style.js
    │   ├── List
    │   │   ├── index.jsx
    │   │   └── style.js
    │   ├── ListArea
    │   │   ├── index.jsx
    │   │   └── style.js
    │   └── index.js
    ├── connect.js
    ├── containers
    │   └── App
    │       └── index.js
    ├── index.js
    ├── modules
    │   ├── fetchLogic.js
    │   ├── getFavoItems.js
    │   ├── getSearch.js
    │   └── useWindowWidth.js
    ├── pages
    │   └── MainView
    │       └── index.jsx
    ├── reducers
    │   ├── combineReducers.js
    │   ├── favorite.js
    │   ├── index.js
    │   └── posts.js
    └── store.js
```

It seems like similar to redux architecture. But there are no redux dependencies in this example.
and main logic is in `index.js` where is a root.
```jsx
import React from 'react';
import { render } from 'react-dom';
import reducers from './reducers';
import Provider from './Provider';
import App from './containers/App';

document.body.style.margin = 0;

const Main = () => (
  <Provider reducer={reducers}>
    <App />
  </Provider>
);

render(<Main />, document.querySelector('#app'));
```
This `Provider` component has a reducer props, which passes to Context API.
take a look at `Provider` 's logic.

```jsx
import React, { useState, useReducer, useEffect } from 'react';
import Context from './Context';

type Props = {
  children: any,
  reducer: () => {}
};

const Provider = ({ children, reducer }: Props) => {
  const [store, dispatch] = useReducer(reducer);
  const [state, setState] = useState({ isLoaded: false });

  useEffect(() => {
    dispatch({ type: '@init' });
    setState({ isLoaded: true });
  }, []);

  return (
    <Context.Provider value={{ dispatch, store }}>
      {state.isLoaded ? children : false}
    </Context.Provider>
  );
};

export default Provider;
```
`Provider` component has 2 props. 1st one is `children` , second one is `reducer` .
Inside of `useEffect` 's `dispatch` is, it's necessary for making store from reducer.
Same as redux's reducer, it is mandatry to set default state params in each reducer otherwise it will occur unexpected error.
And inside of `combineReducer.js` , it's combined each reducer which is being set as argument in combineReducer function.
Take a look at inside of `combineReducer.js` .
```js
const combineReducers = reducer => {
  return (state = {}, action) => {
    const keys = Object.keys(reducer);
    const nextReducers = {};
    for (let i = 0; i < keys.length; i++) {
      const invoke = reducer[keys[i]](state[keys[i]], action);
      nextReducers[keys[i]] = invoke;
    }
    return nextReducers;
  };
};

export default combineReducers;
```
I mimicked redux combineReducer. I didn't know that reducer will be invoked every single time when action is dispatched.

### connect logic
connect logic is really simple Higher Order Component.
```jsx
import React, { useContext } from 'react';
import Context from './Context';

const connect = (mapState, mapDispatch) => {
  return WrappedComponent => {
    return () => {
      const { store, dispatch } = useContext(Context);
      return (
        <WrappedComponent {...mapState(store)} {...mapDispatch(dispatch)} />
      );
    };
  };
};

export default connect;
```

to use Context API as Hooks is so simple to use it. share store to mapState, share dispatch to mapDispatch, then you can use mapStateToProps and mapDispatchToProps like redux in presentational component everywhere if you connect it.

```jsx
const App = ({ posts, addTodo, addFavoItem, favorite }) => {
  /* ...logics */
  return <MainView {...hundlers} />;
};

const mapStateToProps = store => ({
  posts: store.posts.data,
  favorite: store.favorite.favorite_posts
});

const mapDispathToProps = dispatch => ({
  addTodo: param => dispatch(addTodo(param)),
  addFavoItem: param => dispatch(addFavoItem(param))
});

export default connect(
  mapStateToProps,
  mapDispathToProps
)(App);

```

Seems like redux, right?

## In conclusion.
In my humble opinion, I think it's really difficult to replace redux for using hooks api like redux. but it's possible and you can make similar logic like redux.
but if you are using redux middleware like redux-saga, you might have to think how to optimize those middleware.
And I wanna try to replace redux from example app which is using redux-saga or thunk or whatever famous library which people are heavily using in redux environment.

Another thing is that I'm feeling important, to use hooks api is improving DX for you definitely. So far I would love that. I might write something tutorial about hooks which is more porite and neat than this article. haha

Thanks and if you have a question, feel free to reach out to me. Any question is ok. 
Bye!!