Next.js로 프로젝트 시작(typescript + redux)

뱀기·2021년 12월 11일
0
  1. npx create-next-app
  2. root 디렉토리에 tsconfig.json 파일을 만들어준다.
  3. npm install --save-dev typescript @types/react @types/react-dom @types/node
  4. npm run dev
  5. _app.tsx로 바꿈.
  6. 코드 수정
import { AppProps } from 'next/app'
import '../styles/globals.css'

function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

export default MyApp
  1. redux설정
  • npm install redux react-redux next-redux-wrapper
  • npm install -d redux-devtools-extension @types/next-redux-wrapper @types/react-redux
  1. 스토어 폴더 안에 파일 추가.
  • store/actions/actionTypes.ts
export const INCREASE = 'counter/INCREASE'
export const DECREASE = 'counter/DECREASE'
  • store/actions/count.ts
import {INCREASE, DECREASE} from './actionTypes';

export const countUp = () => {
    return {
        type: INCREASE
    }
}

export const countDown = () => {
    return {
        type: DECREASE
    }
}
  • store/reducers/count.ts
import { ActionProps, CounterState } from 'store/types/state';
import {INCREASE, DECREASE} from 'store/actions/actionTypes'

const initialState: CounterState = { value: 0 };

export default (state = initialState, action: ActionProps) => {
    switch (action.type) {
        case INCREASE:
            return { ...state, value: state.value += 1 }
        case DECREASE:
            return { ...state, value: state.value -= 1 }

        default:
            return state;
    }
}
  • store/reducers/index.ts
import { combineReducers } from "redux";
import counter from "./count";

const rootReducer = combineReducers({
    counter
});

export default rootReducer

export type RootState = ReturnType<typeof rootReducer>;
  • store/types/state.ts
export interface ActionProps {
    type: string
}

export interface CounterState {
    value: number
}
  • store/index.ts
import { createStore, applyMiddleware, Middleware, StoreEnhancer } from "redux"
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 });
  1. next에 redux store를 주입한다.
  • _app.tsx
import { AppProps } from 'next/app'
import {ThemeProvider} from 'styled-components';
import { wrapper } from 'store';

// import '../styles/globals.css'
import GlobalStyle from 'styles/global-styles';
import {theme} from 'styles/theme';

const MyApp = ({ Component, pageProps }: AppProps) => {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <Component {...pageProps} />
    </ThemeProvider>
  )
}

export default wrapper.withRedux(MyApp)
  • pages/index.tsx
import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {RootState} from 'store/reducers'
import { countUp, countDown } from 'store/actions/count';

import styles from 'styles/Home.module.css'

const Home = () => {
  const dispatch = useDispatch();
  const {value} = useSelector((state: RootState) => state.counter)

  const upEvent = useCallback(() => {
    dispatch(countUp())
  }, [])

  const downEvent = useCallback(() => {
    dispatch(countDown())
  }, [])

  return (
    <div className={styles.home}>
      <div className={styles['counter__text']}>{value}</div>
      <div className={styles['button__area']}>
        <button onClick={upEvent}>Up</button>
        <button onClick={downEvent}>Down</button>
      </div>
    </div>
  )
}

export default Home

0개의 댓글