이번 글을 통해 배워갈 내용
- TypeScript와 함께 useReducer를 사용하는 방법
UseReducer 6가지 꿀 정보
1.
useReducer Hook은 useState Hook과 비슷한 성질을 가집니다.
2.
필요시 initFunction 도 받아서 쓸 수 있습니다.
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialState initFunction)
3.
useReducer Hook은 reducer, initialState을 인자로 받습니다.
reducer 함수는 state의 로직을 포함하고
initialState 말 그대로 초기 상태입니다.
4.
useReducer Hook은 현재 state와 dispatch method를 반환합니다.
5.
여러 개의 값들을 state 관리할 때
useState 대신 useReducer를 많이 사용합니다.
6.
dispatch를 callbacks대신에 내려서
Performance를 높일 수 있습니다.
코드 예시
useReducer를 활용해서
학생을 추가 삭제 그리고 전체 삭제하는 컴포넌트입니다.
먼저 타입들을 선언해줍니다.
원칙상 실무처럼 파일을 나누지 않고
교육적 용도로 하나의 파일에 작성했습니다.
번호 타입이며 있을 수 있고 없을 수 도있는 idx 값과
문자열 타입의 name이 있습니다.
State에는 학생 타입의 배열이 들어있고
최초 State인 initialSchoolState에는 빈 학생 배열이 들어 있습니다.
액션은 학생을 추가하는 ADD_STUDENT,
하나 삭제하는 DEL_STUDENT,
그리고 전체 삭제하는 DEL_ALL 이 있습니다.
interface Props {}
type Student = {
idx?: number;
name?: string;
};
type State = {
students: Student[];
};
const initialSchoolState: State = {
students: [],
};
enum ActionKind {
ADD_STUDENT = 'ADD_STUDENT',
DEL_STUDENT = 'DEL_STUDENT',
DEL_ALL = 'DEL_ALL',
}
reducer는 state(상태) 값으로 위에 선언한 State 타입을 받고
action으로는 type과 payload를 받습니다.
액션의 종류에 따라서 학생을 추가, 하나 삭제 혹은 전체 삭제합니다
const reducer = (state: State, action: { type: any; payload: Student }): State => {
console.log(state);
switch (action.type) {
case ActionKind.ADD_STUDENT:
return { ...state, students: [...state.students, action.payload] };
case ActionKind.DEL_STUDENT: {
return { ...state, students: [...state.students.filter((s) => s.idx !== action.payload.idx)] };
}
case ActionKind.DEL_ALL:
return { ...state, students: [] };
default:
throw new Error();
}
};
useReducer로 Hook을 사용하며
Render 하는 부분은 아래와 같습니다.
const LearnUseReducer: FunctionComponent<Props> = () => {
const [state, dispatch] = useReducer(reducer, initialSchoolState);
const { students } = state;
return (
<>
{students.map((st) => {
return <div key={st.idx}> {st.name} </div>;
})}
<br />
<button
onClick={() => dispatch({ type: ActionKind.ADD_STUDENT, payload: { idx: state.students.length + 1, name: '학생-' + state.students.length } })}
>
{' '}
학생추가{' '}
</button>
<button onClick={() => dispatch({ type: ActionKind.DEL_STUDENT, payload: { idx: state.students.length } })}> 학생삭제</button>
<button onClick={() => dispatch({ type: ActionKind.DEL_ALL, payload: {} })}> 학생 전체 삭제</button>
</>
);
};
전체 코드
import { FunctionComponent, useReducer } from 'react';
interface Props {}
type Student = {
idx?: number;
name?: string;
};
type State = {
students: Student[];
};
const initialSchoolState: State = {
students: [],
};
enum ActionKind {
ADD_STUDENT = 'ADD_STUDENT',
DEL_STUDENT = 'DEL_STUDENT',
DEL_ALL = 'DEL_ALL',
}
const reducer = (state: State, action: { type: any; payload: Student }): State => {
console.log(state);
switch (action.type) {
case ActionKind.ADD_STUDENT:
return { ...state, students: [...state.students, action.payload] };
case ActionKind.DEL_STUDENT: {
return { ...state, students: [...state.students.filter((s) => s.idx !== action.payload.idx)] };
}
case ActionKind.DEL_ALL:
return { ...state, students: [] };
default:
throw new Error();
}
};
const LearnUseReducer: FunctionComponent<Props> = () => {
const [state, dispatch] = useReducer(reducer, initialSchoolState);
const { students } = state;
return (
<>
{students.map((st) => {return <div key={st.idx}> {st.name} </div>;})}
<br />
<button onClick={() => dispatch({ type: ActionKind.ADD_STUDENT, payload: { idx: state.students.length + 1, name: '학생-' + state.students.length } })}> 학생추가 </button>
<button onClick={() => dispatch({ type: ActionKind.DEL_STUDENT, payload: { idx: state.students.length } })}> 학생삭제</button>
<button onClick={() => dispatch({ type: ActionKind.DEL_ALL, payload: {} })}> 학생 전체 삭제</button>
</>
);
};
export default LearnUseReducer;
한 줄 요약
State가 많다면 useState 대신에 useReducer를 쓰면 깔끔
참조 및 인용
https://reactjs.org/docs/hooks-reference.html
https://stackoverflow.com/questions/65420468/converting-react-usereducer-to-typescript
'Javascript > React' 카테고리의 다른 글
React에 카카오 지도 넣는 방법 (초간단) (Client Side Render) (0) | 2023.06.18 |
---|---|
React로 이미지 업로드 및 필터 적용하고 출력해보기 (0) | 2022.11.19 |
리액트에서 여러 체크박스들을 하나의 컴포넌트로 재활용 해보기 ts (0) | 2022.06.22 |
김씨가 리액트에서 함수 활용하는 비법 한가지 (0) | 2022.05.31 |
React Hook State 묶어서 쓰는 한가지 방법 (0) | 2022.03.26 |