Redux를 설정전 Next, Typescript 설정은 저의 다른 글에서 확인할 수 있습니다.
Redux 설정
1. Redux관련 모듈을 설치합니다.
npm install redux react-redux next-redux-wrapper
npm install -d redux-devtools-extension @types/next-redux-wrapper @types/react-redux
모듈 정보는 링크에서 확인하면 좋을것 같습니다 ko.redux.js.org/introduction/installation/
redux-devtools-extenstion 크롬 확장 툴을 설치하기실 바랍니다. chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd/related
아 참고로저는 tsconfig.json 파일을 수정하여 디렉토리 경로를 절대갑으로 할당하였습니다.
"paths": {
"@/components/*": ["components/*"],
"@/store/*": ["store/*"],
"@/utils/*": ["utils/*"],
"@/api/*": ["api/*"],
"@/config/*": ["config/*"],
"@/styles/*": ["styles/*"],
},
위내용을 tsconfig.json 파일에 추가합니다 전문이 이러합니다.
{
"compilerOptions": {
"target": "es5",
"baseUrl": ".",
"paths": {
"@/components/*": ["components/*"],
"@/store/*": ["store/*"],
"@/utils/*": ["utils/*"],
"@/api/*": ["api/*"],
"@/config/*": ["config/*"],
"@/styles/*": ["styles/*"],
},
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
위 설정을 추가하면 모듈 및 파일을 import 받을때 지정한 경로를 절대경로로 사용할 수 있다.
2 store 폴더 안에 해당 파일들과 코드를 추가한다.
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 });
3. next 에 redux store 을 주입한다. (_app.tsx 코드 수정)
pages/_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)
4. redux가 잘 작동하는지 확인
styles/Home.module.css 수정
.home {
width: 500px;
height: 500px;
background-color: #ededed;
}
.counter__text {
width: 100%;
font-size: 30px;
font-weight: bold;
text-align: center;
}
.button__area {
width: 100%;
text-align: center;
}
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
위 처럼 코드를 수정하고 up down 버튼을 눌러 보면 값이 바뀌는것을 확인할 수 있다.
'Tech > React' 카테고리의 다른 글
Next + Typscript + Redux + Redux-Saga 설정 (0) | 2021.03.11 |
---|---|
Next + Typescript 설정 (0) | 2021.03.11 |
Next.js(react) 프로젝트 시작 (0) | 2021.03.11 |
댓글