react-redux
1. 모듈리듀서
1) 액션타입 지정
2) 액션생성 함수
3) 초기값
4) 리듀서 함수 작성
-> 루트리듀서
2. 스토어 생성
const store = createStore(루트리듀서)
<Provider store={store}>
<App/>
</Provider>
3.컴포넌트 생성
1) 컨테이너 컴포넌트
2) 프레젠테이션 컴포넌트
npx create-react-app ts-redux-tutorial --template typescript
ts-redux-tutorial
npm install redux
npm install react-redux
ts 안붙어있는 react-redux는 타입스크립트를 모듈에 적용시켜야 함
npm install @types/react-redux
* 카운터 만들기
1. 모듈리듀서 -> 루트리듀서 -> combine
2. 컴포넌트
modules/counter.ts
↓
// 1. 액션타입
// 2. 액션을 리턴해주는 함수
// 3. 초기값
// 4. 리듀서 만들기
// 액션타입
export const INCREASE = "counter/INCREASE" as const;
export const DECREASE = "counter/DECREASE" as const;
export const INCREASE_BY = "counter/INCREASE_BY" as const;
// 액션 생성함수
export const increase = () => ({ type: INCREASE })
export const decrease = () => ({ type: DECREASE })
export const increaseBy = (diff: number) => ({
type: INCREASE_BY,
payload: diff
})
// 스테이트의 타입을 지정
type CounterState = {
count: number;
}
// 초기상태 생성
const initialState = {
count: 0
}
// 리듀서 액션 타입지정
// ReturnType<typeof ---> 특정함수의 반환값을 추론
// 리듀서 액션 타입지정
type CounterAction =
| ReturnType<typeof increase>
| ReturnType<typeof decrease>
| ReturnType<typeof increaseBy>
// 리듀서 만들기
export default function counter(state: CounterState = initialState, action: CounterAction) : CounterState{
switch(action.type) {
case 'counter/INCREASE':
return { count: state.count + 1 };
case 'counter/DECREASE':
return { count: state.count - 1 };
case 'counter/INCREASE_BY':
return { count: state.count + action.payload };
default:
return state;
}
}
modules/index.ts
import { combineReducers } from "redux";
import counter from "./counter"
const rootReducer = combineReducers({ counter });
export default rootReducer;
// 나중에 이 타입을 컨테이너 컴포넌트에서 불러와서 사용해야하므로
// 내보내줍니다.
export type RootState = ReturnType<typeof rootReducer>
App.tsx
import React from 'react';
import './App.css';
import ContainerCounter from './containers/ContainerCounter';
function App() {
return (
<div className="App">
<ContainerCounter />
</div>
);
}
export default App;
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore } from 'redux';
import rootReducer from './modules';
import { Provider } from 'react-redux';
const store = createStore(rootReducer)
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
containers/CountainerCounter.tsx
import React from 'react';
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux';
import Counter from '../components/Counter';
import { RootState } from '../modules';
import { decrease, increase, increaseBy } from '../modules/counter'
const ContainerCounter = () => {
const count = useSelector((state:RootState)=>state.counter.count);
const dispatch = useDispatch();
const onIncrease = () => {
dispatch(increase())
}
const onDecrease = () => {
dispatch(decrease());
}
const onIncreaseBy = (diff:number) => {
dispatch(increaseBy(diff));
}
return (
<Counter count={count}
onDecrease={onDecrease}
onIncrease={onIncrease}
onIncreaseBy={onIncreaseBy}/>
);
};
export default ContainerCounter;
components/Counter.tsx
import React from 'react';
type CounterProps = {
count: number;
onIncrease: () => void;
onDecrease: () => void;
onIncreaseBy: (diff:number) => void;
}
const Counter = ({count, onIncrease, onDecrease, onIncreaseBy}:CounterProps) => {
return (
<div>
<h1>{count}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
<button onClick={()=>onIncreaseBy(5)}>+5</button>
</div>
);
};
export default Counter;
'Stack > TypeScript' 카테고리의 다른 글
[TS / React] typesafe-actions을 이용한 refactoring (0) | 2022.07.29 |
---|---|
[TS / React] Redux로 To-do List 구현 (0) | 2022.07.29 |
[TS / React] Context API (0) | 2022.07.28 |
[TS / React] To-Do List 구현 (0) | 2022.07.27 |
[TS / React] props 전달 (0) | 2022.07.27 |