- 구조분해할당
useReducer의 개념
상태를 관리하게 될 때 useState 를 사용하는것 말고도 다른 방법이 있다. 바로 useReducer 라는 Hook을 사용하는것인데, 이 Hook 함수를 사용하면 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리시킬 수 있다. 상태 업데이트 로직을 컴포넌트 바깥에 작성 할 수도 있고, 심지어 다른 파일에 작성 후 불러와서 사용 할 수도 있다.
즉, 다른 컴포넌트에서도 재사용을 하기위해 로직을 따로 정의할 수 있어, 유지보수에 유리하고 간결한 코드를 내보일 수 있다는 장점이 있다.
useReducer의 사용방법
const [state, dispatch] = useReducer(reducer, initialState);
useReducer 에 넣는 첫번째 파라미터는 reducer 함수이고, 두번째 파라미터는 초기 상태이다.
여기서 state 는 우리가 앞으로 컴포넌트에서 사용 할 수 있는 상태를 가르키게 되고, dispatch 는 액션을 발생시키는 함수라고 이해하면 된다.
dispatch({ type: 'INCREMENT', 액션객체에 보낼정보1, 액션객체에 보낼정보2 })
다음과 같이 작성하면 따로 작성해둔 액션이 발생된다.
useReducer의 사용예제
person.reducer.js (분리된 로직)
export default function personReducer(person, action) {
switch (action.type) {
case "updated": {
const { prev, current } = action;
return {
...person,
mentors: person.mentors.map((mentor) => {
if (mentor.name === prev) {
return { ...mentor, name: current };
}
return mentor;
}),
};
}
case "added": {
const { name, title } = action;
return {
...person,
mentors: [...person.mentors, { name, title }],
};
}
case "deleted": {
return {
...person,
mentors: person.mentors.filter((mentor) => mentor.name !== action.name),
};
}
default: {
throw Error(`알수없는 액션 타입이다: ${action.type}`);
}
}
}
- 이러한 분리된 로직은 reducer함수를 사용할 컴포넌트파일 하단부에 같이 작성해두어도 된다.
const { prev, current } = action;
// 구조분해할당이다. 아래의 두줄을 동시에 쓴것과 같은 의미이다.
const prev = action.prev;
const current = action.current;
- 구조분해할당이 쓰였다.
AppMentors.jsx (분리해둔 로직 가져와 활용)
import React, { useReducer } from "react";
import personReducer from "./reducer/person-reducer";
export default function AppMentor() {
const [person, dispatch] = useReducer(personReducer, initialPerson);
const handleUpdate = () => {
const prev = prompt(`누구의 이름을 바꾸고 싶은가요?`);
const current = prompt(`이름을 무엇으로 바꾸고 싶은가요?`);
dispatch({ type: "updated", prev, current });
};
const handleAdd = () => {
const name = prompt(`멘토의 이름은?`);
const title = prompt(`멘토의 직함은?`);
dispatch({ type: "added", name, title });
};
const handleDelete = () => {
const name = prompt(`누구를 삭제하고 싶은가요?`);
dispatch({ type: "deleted", name });
};
return (
<div>
<h1>
{person.name}는 {person.title}
</h1>
<p>{person.name}의 멘토는:</p>
<ul>
{person.mentors.map((mentor, index) => (
<li key={index}>
{mentor.name} ({mentor.title})
</li>
))}
</ul>
<button onClick={handleUpdate}>멘토의 이름을 바꾸기</button>
<button onClick={handleAdd}>멘토 추가하기</button>
<button onClick={handleDelete}>멘토 삭제하기</button>
</div>
);
}
const initialPerson = {
name: "엘리",
title: "개발자",
mentors: [
{
name: "밥",
title: "시니어개발자",
},
{
name: "제임스",
title: "시니어개발자",
},
],
};
'React(Docs) > React(Practice)' 카테고리의 다른 글
AppForm_Form을 React에서 다루는 방법 (0) | 2022.12.14 |
---|---|
AppMentors_Immer (0) | 2022.12.12 |
AppMentors_추가/삭제(filter, spread연산자, key) (0) | 2022.12.11 |
AppMentors_배열상태 관리(불변성, map, spread연산자) (0) | 2022.12.11 |
AppXY_객체initialState(transform, onPointerMove) (0) | 2022.12.10 |