-
React와 Typescript 사용Typescript 2022. 6. 17. 16:18
요약해보면 변수, 함수 만들 때 타입지정하면 그냥 끝이다.
먼저 리액트에 타입스크립트를 셋팅해야한다.
npx create-react-app 프로젝트명 --template typescript
이렇게 리액트 프로젝트명에 typescript를 설치해주고,
아니면 기존 프로젝트에 typescript를 설치하려면
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
이렇게 써주고, 기존 js폴더를 ts로 바꾸면 된다.
그리고 만약, JSX문법을 쓰는 파일은 .tsx 확장자로 쓰면 된다.
일반 변수나 함수에는 지금까지 한 것처럼 잘 타입정해서 하면 된다.
하지만, JSX표현하는 타입이 따로 있다.
let 박스 :JSX.Element = <div></div> let 버튼 :JSX.Element = <button></button> let 박스 :JSX.IntrinsicElements['div'] = React.createElement('div'); let 버튼 :JSX.IntrinsicElements['button'] = <button></button>;
위처럼 정의하며, 밑은 기본태그들 div a button같은 태그들은 IntrinsicElements[]을 이용하면 더 구체적이게 적을 수 있다.
근데 보통상황은 Element만 써도 가능하다. 그리고 React.createElement('div');은 <div></div>가 남게 된다.
component를 만들 때 타입지정을 해보고, useState까지 추가로 알아보자.
type AppProps = { name: string; }; let [user,setUser] = useState(['kim']) function App () { return ( <Profile name="철수"></Profile> ) } function Profile(props : {name : string}) :JSX.Element { return ( <div>{props.name}입니다.</div> ) }
Profile컴포넌트를 만들었을 때, JSX를 return으로 반환하면 JSX.Element를 적어주면 된다.
그리고 props를 쓰려면 보낸 props의 타입을 오브젝트 형식으로 타입을 지정해주면 된다. 또는 위의 타입앨리어스로
props: AppProps를 적어줄 수 있다.
그리고 useState는 자동으로 타입지정이 되므로 신경쓰지 않아도 된다.
이제 잠깐, Redux 에서 타입지정을 알아보자.
import { Provider } from 'react-redux'; import { createStore } from 'redux'; interface Counter { count : number } const 초기값 :Counter = { count: 0 }; function reducer(state = 초기값, action :{type : string} ) { if (action.type === '증가') { return { count : state.count + 1 } } else if (action.type === '감소'){ return { count : state.count - 1 } } else { return initialState } } const store = createStore(reducer); // store의 타입 미리 export 해두기 export type RootState = ReturnType<typeof store.getState> ReactDOM.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById('root') )
버튼을 누르면 state에 +1을 해주는 예제인데, Counter라는 interface를 만들고, 타입지정을 해서 초기값 변수에 0을 넣어 모든 컴포넌트가 공유할 state를 만들어주고, reducer을 통해 state를 수정하게 만들어준다. reducer함수에도 타입지정을 할 수 있는데, reducer의 state = 초기값은 기본값이라 자동으로 타입을 가지게 되므로 할 필요 없다.
그리고 action에 타입을 action :{type : string} 이렇게 지정해주면 된다.
꺼내올 땐
import React from 'react'; import { useDispatch, useSelector } from 'react-redux' import { Dispatch } from 'redux' import {RootState} from './index' function App() { const 꺼내온거 = useSelector( (state :RootState) => state ); const dispatch :Dispatch = useDispatch(); return ( <div className="App"> { 꺼내온거.count } <button onClick={()=>{dispatch({type : '증가'})}}>버튼</button> <Profile name="kim"></Profile> </div> ); }
useSelector를 이용해 (state :RootState) => state 라고 RootState타입을 export해온걸 받아와서 타입지정을하고 꺼내온거에 담을 수 있다.
그리곤, dispatch를 이용해 state 수정요청을 날릴 수 있다. 여기서 Dispatch로 타입지정도 할 수 있다.
신문법으론 redux toolkit을 알아보자.
npm install @reduxjs/toolkit
toolkit을 받아오고
import { createSlice, configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; const 초기값 = { count: 0, user : 'kim' }; const counterSlice = createSlice({ name: 'counter', initialState : 초기값, reducers: { increment (state){ state.count += 1 }, decrement (state){ state.count -= 1 }, incrementByAmount (state, action :any){ state.count += action.payload } } }) let store = configureStore({ reducer: { counter1 : counterSlice.reducer } }) //state 타입을 export 해두는건데 나중에 쓸 데가 있음 export type RootState = ReturnType<typeof store.getState> //수정방법 만든거 export export let {increment, decrement, incrementByAmount} = counterSlice.actions
이렇게 쓰면, 함수라 보기가 좋고, state 수정시 사본을 만들 필요가 없다. 이 역시 초기값에 타입지정을 해주면 된다.
action에 타입을 지정하려면
import { createSlice, PayloadAction } from '@reduxjs/toolkit' (상단 생략) incrementByAmount (state, action: PayloadAction<number>){ state.value += action.payload },
이렇게 쓰면된다.
리덕스 너무 복잡한거 같은뎅?.. 어렵다!
'Typescript' 카테고리의 다른 글
외부파일 이용시 declare & ambient module (0) 2022.06.17 array에 붙이는 tuple type (0) 2022.06.17 타입을 파라미터로 입력하는 Generic (0) 2022.06.17 타입 import/export와 namespace (0) 2022.06.17 protected, static (0) 2022.06.17