ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

    댓글

Designed by Tistory.