일안하고블로그

[NextJs] 4. nextjs redux typescript 적용 예제 counter 만들기 본문

React/NextJS

[NextJs] 4. nextjs redux typescript 적용 예제 counter 만들기

대한93 2021. 1. 27. 11:27

next js

이번에 다룰 내용은 typescript interface /action / redux / reducer 을 통해서 counter 을 만드는 예제를 만들어 보겠습니다 .

이전에 react로  counter예제를 만들어 보셨으면 이해하기 편합니다. 타입스크립트하고 redux를 어느정도 이해하시면 내용은 조금 많지만 금방 이해하실수 있을거에요 . 

 

1. 명령어를 입력해주세요 . 

yarn add redux next-redux-wrapper 
yarn add --dev  redux-devtools-extension redux-logger

next 와 react를 연결하기 위해서 next-redux-wrapper가 필요합니다. 

나머지는 미들웨어 설정을 하면서 결과를 보기 위해 받습니다. 

 

2. store 생성 

import { createStore, applyMiddleware, compose } from "redux";
import { createWrapper } from "next-redux-wrapper";
import { createLogger } from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";
import rootReducer from "reducer/index";

const configureStore = () => {
	const logger = createLogger();
	const enhancer = compose(composeWithDevTools(applyMiddleware(logger)));
	const store = createStore(rootReducer, enhancer);
	return store;
};

const wrapper = createWrapper(configureStore, { debug: true });

export default wrapper;

 

저는 루트 부분에 store파일을 만들었습니다. 

 

3. 만든 store을 _ app.tsx 파일에 wrapper적용

import { AppProps } from "next/app";
import { NextPage } from "next";
import wrapper from "../store"; //좀전에 만든 store.tsx 파일

const MyApp: NextPage<AppProps> = ({ Component, pageProps }: AppProps) => {
	return (
		<>
			<Component {...pageProps} />
		</>
	);
};

export default wrapper.withRedux(MyApp);

 

4. interfaces 폴더 생성

 

5.다음 파일들을 생성합니다.

interfaces/RootState.tsx

interfaces/index.tsx 

interfaces/counter/counter.interfaces.tsx

interfaces/counter/counterAct.interfaces.tsx

 

6. index.tsx 파일에 소스 추가 해주세요. 

export * from "./counter/counter.interfaces";
export * from "./counter/counterAct.interfaces";

 

7. RootState.tsx파일에 소스추가해주세요. 

import { CompanyState, CounterState } from "./index";

export interface RootStateInterface {
	counter: CounterState;
}

 

8. counter.interfaces.tsx파일에 소스추가 해주세요. 

export interface CounterState {
	count: number;
}

 

9. counterAct.interfaces.tsx 소스추가 해주세요.  

export enum actionTypesCounter {
	COUNTER_INCREMENT = "COUNTER_INCREMENT", // 숫자 + 1
	COUNTER_DECREMENT = "COUNTER_DECREMENT",  // 숫자 - 1
	COUNTER_RESET = "COUNTER_RESET", // 초기화 
}

export type ActionsCounter = CounterIncrement | CounterDecrement | CounterReset;

export interface CounterIncrement {
	type: actionTypesCounter.COUNTER_INCREMENT;
}

export interface CounterDecrement {
	type: actionTypesCounter.COUNTER_DECREMENT;
}

export interface CounterReset {
	type: actionTypesCounter.COUNTER_RESET;
}

 


10.  파일 추가해주세요 . 

reducer/index.tsx 

reducer/counter.tsx 

 

11. reducer/index.tsx 파일에 소스추가해주세요.

 

import { combineReducers, Reducer, AnyAction } from "redux";
import { RootStateInterface } from "interfaces/RootState";
import counter from "./counter";

const rootReducer: Reducer<
	RootStateInterface,
	AnyAction
> = combineReducers<RootStateInterface>({
	counter,
});

export default rootReducer;
export type RootState = ReturnType<typeof rootReducer>;

 

12. reducer/counter.tsx 파일에 소스추가 해주세요. 

import { HYDRATE } from "next-redux-wrapper";
import {
	CounterState,
	actionTypesCounter,
	ActionsCounter,
} from "../interfaces";

export const initialState: CounterState = {
	count: 0,
};

interface HydratePayload {
	counter: CounterState;
}

const counter = (
	state = initialState,
	action: ActionsCounter | { type: typeof HYDRATE; payload: HydratePayload },
): CounterState => {
	switch (action.type) {
		case HYDRATE:
			return { ...state, ...action.payload.counter };
		case actionTypesCounter.COUNTER_INCREMENT:
			return {
				...state,
				...{ count: state.count + 1 },
			};

		case actionTypesCounter.COUNTER_DECREMENT:
			return {
				...state,
				...{ count: state.count - 1 },
			};

		case actionTypesCounter.COUNTER_RESET:
			return {
				...state,
				...{ count: initialState.count },
			};

		default:
			return state;
	}
};
export default counter;

 

13. 마지막으로 pages/counter/index.tsx 파일을 만들어서 소스를 추가해주세요. 

 

import React from "react";
import { useDispatch, useSelector } from "react-redux";
import wrapper from "store";
import { RootStateInterface } from "interfaces/RootState";
import { CounterState } from "interfaces";
import {
	counterIncrement,
	counterDecrement,
	counterReset,
} from "actions/actCounter";

const Counter = () => {
	const { count } = useSelector(
		(state: RootStateInterface): CounterState => state.counter,
	);
	const dispatch = useDispatch();
	const handleClick = (num: number) => {
		if (num === 1) {
			dispatch(counterIncrement());
		} else if (num === 0) {
			dispatch(counterDecrement());
		} else if (num === 2) {
			dispatch(counterReset());
		}
	};
	return (
		<div>
			<div>현재값:{count}</div>
			<div>
				<button onClick={() => handleClick(1)}>+</button>
				<button onClick={() => handleClick(0)}>-</button>
				<button onClick={() => handleClick(2)}>reset</button>
			</div>
		</div>
	);
};
export const getStaticProps = wrapper.getStaticProps(async (context) => {
	console.log(context);
});

export default Counter;

 

마지막으로 명령어를 입력해주세요. 

yarn dev

 

localhost:3000/counter에 접속하시면

 

다음과 같이 나오시면 성공입니다. 

Comments