Using "useSelector", "useDispatch" hook in Next.js

Viewed 3433

I'm studying Next.js and have some questions.

Next.js is SSR, so the component gets props using getInitialProps.

I want to add redux store in my next app, so I wrote some codes.

counterAction.ts

const INCREASE = "COUNTER_INCREASE" as const;
const DECREASE = "COUNTER_DECREASE" as const;

const counterIncrease = () => ({
  type: INCREASE,
});

const counterDecrease = () => ({
  type: DECREASE,
});

export default { counterIncrease, counterDecrease };

counterReducer.ts

import counterActions from "../actions/counterActions";
import { HYDRATE } from "next-redux-wrapper";

type CounterAction =
  | ReturnType<typeof counterActions.counterIncrease>
  | ReturnType<typeof counterActions.counterDecrease>
  | { type: typeof HYDRATE };

type CounterState = {
  value: number;
};

const initialState: CounterState = {
  value: 0,
};

const count = (state: CounterState = initialState, action: CounterAction) => {
  switch (action.type) {
    case HYDRATE:
      return { ...state };
    case "COUNTER_INCREASE":
      return { ...state, value: state.value + 1 };
    case "COUNTER_DECREASE":
      return { ...state, value: state.value - 1 };
    default:
      return state;
  }
};

export default count;

store/index.ts

import rootReducer from "./reducers";
import { MakeStore, createWrapper } from "next-redux-wrapper";

const bindMiddleware = (middleware: Middleware[]): StoreEnhancer => {
  if (process.env.NODE_ENV !== "production") {
    const { composeWithDevTools } = require("redux-devtools-extension");
    return composeWithDevTools(applyMiddleware(...middleware));
  }
  return applyMiddleware(...middleware);
};

const makeStore: MakeStore<{}> = () => {
  const store = createStore(rootReducer, {}, bindMiddleware([]));
  return store;
};

export const wrapper = createWrapper<{}>(makeStore, { debug: true });

and add in _app.tsx,

export default wrapper.withRedux(MyApp);

It works very well, but is it OK accessing this store with useSelector? For example, this is my counter.tsx.

import { NextPage } from "next";
import React, { Fragment } from "react";
import { useSelector, useDispatch } from "react-redux";
import { RootStore } from "../store/reducers";
import allActions from "../store/actions";

const Counter: NextPage<{}> = () => {
  const count = useSelector((store: RootStore) => store.count.value);
  const dispatch = useDispatch();

  const handleIncrease = () =>
    dispatch(allActions.counterActions.counterIncrease());

  const handleDecrease = () =>
    dispatch(allActions.counterActions.counterDecrease());

  return (
    <Fragment>
      <h1>{count}</h1>
      <button onClick={handleIncrease}>+1</button>
      <button onClick={handleDecrease}>-1</button>
    </Fragment>
  );
};

export default Counter;

In this code, I tried to access the redux store with useSelector, and useDispatch.

Is this clean code in next.js and does it work in production level?

Thanks for reading.

0 Answers
Related