TypeScript(with redux)

Jay·2021년 2월 20일
0

npx create-react-app [프로젝트명] --template typescript
npm i redux react-redux
npm i @types/react-redux : react-redux는 타입스크립트가 적용 안되어있기 때문에 이렇게 @types에서 설치해준다.

count 앱 만들기

modules/counter.ts

//액션 타입 정의
const INCREASE = 'counter/INCREASE' as const;
const DECREASE = 'counter/DECREASE' as const;
const INCREASE_BY = 'counter/INCREASE_BY' as const;
// as const를 붙이기 전까지는 타입을 예측할 수 없다.
// 붙이고 나면 정상적으로 타입이 counter/INCREASE로 나오는걸 볼 수 있다.

//액션 생성함수
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:CounterState = {
	count:0
}

// 이렇게 위에 선언한 함수의 결과물을 가져올 수 있다.
type CounterAction = 
 |ReturnType<typeof increase>
 |ReturnType<typeof decrease>
 |ReturnType<typeof increaseBy>

//리듀서 함수 시작
function counter(state: CounterState = initialState, action:CounterAction):CounterState{
   switch (action.type){
      case INCREASE: 
        return {count:state.count +1}
      case DECREASE:
        return {count:state.count -1}
      case INCREASE_BY:
        return {count:state.count + action.payload}
      default:
        return state;
    }
}

export default counter;

modules/index.ts

import {combineReducers} from 'redux';
import counter from './counter';

//루트리듀서 만들기
const rootReducer = combineReducers({
	counter
})

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

index.tsx

import React from 'react';
import ReactDom from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import {Provider} from 'react-redux';
import {createStore} from 'redux'
import rootReducer from './modules';

const store = createStore(rootReducer);

ReactDOM.render(
	<Provider store={store}>
  		<App/>
    </Provider>.
	document.getElementById('root')
);

components/Counter.tsx

import React from 'react';

type CounterProps = {
  count: number;
  onIncrease: () =>void;
  onDecrease: () =>void;
  onIncreaseBy: (diff:number)=> void;
};

function 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;

container/CounterContainer.tsx

import React from 'react';
import Counter from '../components/Counter';
import {useSelector} from 'react-redux';
import {RootState} from '../modules';

function CounterContainer() {
 const count = useSelector((state:RootState) => state.counter.count);
 const dispatch = useDispatch();

 const onIncrease = () => {
 dispatch(increase());
 }
  
 const onDecrease = () =>{
  dispatch(decrease()); 
 }
 
 const onIncreaseBy = (diff:number) => {
  dispatch(increase(diff)); 
 }

  return (
    <Counter
  	 count={count}
         onIncrease={onIncrease}
   	 onDecrease={onDecrease}
  	 onIncreaseBy={onIncreaseBy}
 	/>
   )
 }

export default CounterContainer

App.tsx

import React from 'react';
import CountContainer from './containers/CounterContainer';

const App:React.FC = () => {
  return <CounterContainer />  
}
  
export default App;
profile
programming!

0개의 댓글