useReducer로 기존에 만들었던 투두리스트 앱의상태 관리 훅을
useState가 아닌, useReducer로 변경하여상태 관리를 해보자.
1. useReducer로 상태관리 훅 사용
먼저 기존의
state를 삭제하고 useReducer를 활용한 state를 만들자.첫 번째 인수로 실질적으로 상태를 변경하는 함수
ruducer를 넣고초기값으로
mockData를 넣어주자.const [todos, dispatch] = useReducer(reducer, mockData);다음으로는
reducer 함수를 만들어보자.첫 번째 인수로 현재 상태를 의미하는
state두 번째 인수로는 요청 형태를 담는
action 객체를 넣어주자.function reducer(state, action) {}2. onCreate 함수 수정
기존에 만들어두었던
onCreate 함수 내용을 삭제하고dispatch를 호출하는 코드를 넣어주자.const onCreate = (content) => {
dispatch();
};이 액션 객체에는
type 프로퍼티로 CREATEdate 프로퍼티로 추가될 객체의 값을 넣어주자.const onCreate = (content) => {
dispatch({
type: "CREATE",
data: {
id: idRef.current++,
isComplete: false,
content: content,
date: new Date().getTime(),
},
});
};다음으로
reducer 함수에서 switch문을 작성해서action.type이 CREATE일 때 기존 상태를 스프레드 연산자로 뿌리고그 앞에
action.data에서 적어두었던 정보를 끼워넣을 수 있게 같이 적어주자.function reducer(state, action) {
switch (action.type) {
case "CREATE":
return [action.data, ...state];
}
}추가 잘됨!

3. onUpdate 함수 수정
다음으로는 수정하는 로직을 수정하자.
마찬가지로 기존에 함수 내부에 있던 코드를 삭제하고
dispatch 함수를 호출해주자.const onUpdate = (targetId) => {
dispatch();
};인수로는
UPDATE라는 type과 targetId 프로퍼티를 가진액션 객체를 넣어주자.
const onUpdate = (targetId) => {
dispatch({
type: "UPDATE",
targetId: targetId,
});
};reducer함수로 가서 UPDATE라는 case를 추가해준 뒤현재
state에 map메서드를 호출하여 인수로 item을 받자.각
item을 순회하면서 id가 targetId와 같은 요소를 찾아요소 안의 내용을 스프레드 연산자로 뿌린 후 그 중에서도
isComplete만 토글로 변경될 수 있게 변경해주자.id가 targetId와 일치하지 않을 때는 item을 그대로 넣어주자.삼항연산자로 보다 깔끔하게 작성했다.
function reducer(state, action) {
switch (action.type) {
case "CREATE":
return [action.data, ...state];
case "UPDATE":
return state.map((item) =>
item.id === action.targetId
? { ...item, isComplete: !item.isComplete }
: item,
);
}
}아주 잘되시긔

4. onDelete 함수 수정
마지막으로 삭제 로직도 수정해보자.
마찬가지로
onDelete함수 내에 기존 코드를 제거하고dispatch함수를 호출하여 type과 targetId를 가진액션 객체를 인수로 넣어주자.
const onDelete = (targetId) => {
dispatch({
type: "DELETE",
targetId: targetId,
});
};reducer함수에서 DELETE case를 추가하고filter메서드를 사용하여 id와 targetId가 일치하지 않는 요소만필터링하여 반환하면 삭제를 클릭한 요소는 삭제된다.
마지막엔
default로 현재 상태인 state를 돌려주자.(작성된
case가 아닌 경우에 다른 로직이 실행되는 것 방지)function reducer(state, action) {
switch (action.type) {
case "CREATE":
return [action.data, ...state];
case "UPDATE":
return state.map((item) =>
item.id === action.targetId
? { ...item, isComplete: !item.isComplete }
: item,
);
case "DELETE":
return state.filter((item) => item.id !== action.targetId);
default:
state;
}
}만들었던 노션 정리하기 라는
content를 가진 요소가 제거되었다!
Share article