1. 설치
- 신규설치: npx create-react-app 프로젝트명 --template typescript
- 기존프로젝트에 설치: npm install --save typescript @types/node @types/react @types/react-dom @types/jest
2. tsx파일
- JSX문법이 있는 파일일 경우 tsx파일로!
⭐️ JSX 타입지정
let box :JSX.Element = <div></div>
⭐️ component 타입지정
function Profile() :JSX.Element{
return (
<div>프로필입니다.</div>
)
}
⭐️ props 타입지정
<Profile name="ha0" age="30"></Profile>
function Profile(props :{name: string, age :string}) :JSX.Element{
return (
<div>{props.name}입니다.</div>
)
}
- 더 짧게 하고싶으면 type alias, interface 등을 활용하면 된다.
⭐️state 타입지정
let [user, setUser] = useState('kim')
- 굳이 타입지정안해도 자동으로 되서 신경안써도됨
- 매우 드물지만, stirng | number등으로 state를 가변적인 타입을 지정하고 싶은 경우에는 generic문법을 이용한다.let [user, setUser] = useState<string | number>('kim')
3. redux
🛒 redux 타입지정(전통방식)
☃️ state 저장
state초기값, reducer(state가 변경되는 방법 정의) 생성하기
const 초기값 :{count:number} = {count: 0};
function reducer(state = 초기값, action: {type: string}) {
if(action.type === '증가') {
return {...state, count : state.count + 1}
} else if (action.type === '감소') {
return {...state, count : state.count - 1}
} else {
return 초기값
}
}
const store = createStore(reducer);
// 👇🏻 store의 타입 미리 export해두기
export type RootState = ReturnType<typeof store.getState>
reducer 파라미터 타입지정
👉🏻 state: state에 들어가는 값이 타입을 가지고 있으면 자동으로 타입지정되므로 굳이 타입지정 하지 않아도 됨
👉🏻 action: 타입지정 필요 => 컴포넌트 안에서 state수정요청 날릴 때의 파라미터 타입
☃️ state 사용
useSelector() 파라미터 타입지정
useSelector((state :{count:number}) => state)
👉🏻 하지만 store의 변수 타입을 미리 export해뒀기 때문에 import해서 사용하면 더 간편하게 작성할 수 있다.
import {RootState} from './index'
useSelector((state :RootState) => state)
☃️ state 변경
dispatch 타입지정
import {Dispatch} from 'redux'; // dispatch 타입 import
const dispatch :Dispatch = useDispatch();
...
<button onClick={() => {dispatch({type:'증가'})}}>button</button>
🛒 redux toolkit 이용한 신문법과 타입지정
1. reduxjs/toolkit 라이브러리 설치
npm install @reduxjs/toolkit
2. createSlice import
import { createSlice } from '@reduxjs/toolkit';
3. slice 생성 (state + reducer)
createSlice({name: slice명, initialState: 초기값, reducers: reducer 등록})
const 초기값 :{count :number, user :string}= {count: 0, user: 'ha0'};
const counterSlice = createSlice({
name: 'counter',
initialState: 초기값,
reducers: {
증가(state) {
state.count += 1
},
감소(state) {
state.count -= 1
},
맘대로(state, action :PayloadAction<number>) {
// 두번째 파라미터(action)은 PayloadAction타입으로 지정하고 <>에 어떤 타입으로 파라미터를 받을지 타입을 정해주면 된다.
state.count += action.payload
}
}
})
reducer 파라미터 타입지정
👉🏻 state: state에 들어가는 값이 타입을 가지고 있으면 자동으로 타입지정되므로 굳이 타입지정 하지 않아도 됨
👉🏻 action: 타입지정 필요 => PayloadAction타입<사용할 자료 타입>
4. store에 등록하기
let store = configureStore({
reducer: {
counter1 : counterSlice.reducer
}
})
5. 사용할 reducer 내보내기
- reducer안의 함수명을 export한다.
export let {증가, 감소, 맘대로} = counterSlice.actions;
6. state 사용
- useSelector, useDispatch하는 법은 기존방식과 동일const dispatch :Dispatch = useDispatch()
- const state변수 = useSelector((state :RootState) => state)
- state는 store에 등록된 reducer의 이름으로 꺼내쓴다.
- {state변수.counter1.user}
- dispatch할 때는 export한 함수를 import해서 쓰면 된다.
- import {증가, 감소, 맘대로} from './index'
<button onClick={() => {dispatch(증가())}}>button</button>
🍓 장점 1. 함수형태여서 기존 if문 reducer보다 보기 편하다.
🍓장점 2. state 수정 시 사본만들 필요가 없다. (복사본을 만들어줌)