
이번 글에서 React.js, GraphQL, Apollo를 활용하여 음식 추가, 수정, 삭제 기능을 개발하는 과정을 세부적으로 소개하겠습니다. 이 포스팅은 코드의 핵심 부분을 중심으로 기술적인 내용을 깊이 있게 다루며, 개발자들이 쉽게 이해할 수 있도록 설명합니다.
음식을 추가하는 AddDish 컴포넌트는 Apollo Client의 useMutation 훅을 사용하여 GraphQL 서버에 데이터를 전송합니다. 이 과정에서 다음과 같은 GraphQL 뮤테이션을 사용합니다:
mutation createDish($input: CreateDishInput!) {
createDish(input: $input) {
ok
error
}
}
위 뮤테이션은 CreateDishInput 타입의 입력값을 필요로 하며, 새로운 음식을 생성하는 API를 호출합니다.
const onSubmit = async () => {
const { name, price, description, file, ...rest } = getValues();
// 파일 처리와 옵션 객체 생성 로직
await createDishMutation({
variables: {
input: {
name,
price: +price,
description,
photo: photo,
restaurantId: +restaurantId,
options: optionsObject,
},
},
});
navigate(-1);
};
onSubmit 함수는 폼 데이터를 수집하고, createDishMutation을 호출하여 서버에 데이터를 전송합니다. 성공적으로 데이터가 추가되면 사용자는 이전 페이지로 돌아갑니다.
EditRemoveDish 컴포넌트에서 음식 정보를 수정하고 삭제합니다. 수정과 삭제를 위한 별도의 GraphQL 뮤테이션을 정의합니다:
mutation editDish($input: EditDishInput!) {
editDish(input: $input) {
ok
error
}
}
mutation deleteDish($input: DeleteDishInput!) {
deleteDish(input: $input) {
ok
error
}
}
const onSubmit = async () => {
const { name, price, description, file, ...rest } = getValues();
// 파일 처리와 옵션 객체 생성 로직
await editDishMutation({
variables: {
input: {
dishId: +dishId,
name,
price: +price,
description,
photo: photo,
options: optionsObject,
},
},
});
navigate(-1);
};
const onDelete = async () => {
if (window.confirm("이 음식을 삭제하시겠습니까?")) {
await deleteDishMutation({
variables: {
input: {
dishId: +dishId,
},
},
});
navigate(-1);
}
};
수정하기 버튼을 누르면 onSubmit 함수가 호출되어 변경된 정보를 서버로 전송하고, 삭제하기 버튼을 누를 경우 onDelete 함수가 호출되어 해당 음식을 삭제합니다.
음식 추가 기능에서 다양한 옵션과 세부사항을 관리합니다. optionsObject는 각 옵션의 고유 ID(categoryId)를 매핑하여 옵션과 선택사항(choices)을 생성합니다. 옵션 추가 및 삭제 이벤트는 동적으로 처리되며, onAddOptionClick과 onAddOptionDetailClick 함수를 통해 새 옵션과 세부사항을 상태에 추가합니다.
음식 추가 기능에서는 여러 옵션과 그 세부사항을 관리할 수 있어야 합니다. 각 옵션은 사용자에게 추가 선택사항을 제공합니다.
const optionsObject = optionsNumber.map((categoryId) => {
const choices = optionsDetails[categoryId]?.map((detailId) => {
return {
name: rest[`${categoryId}-${detailId}-optionChoiceName`],
extra: +rest[`${categoryId}-${detailId}-optionChoiceExtra`],
};
}).filter((choice) => choice.name);
return {
name: rest[`${categoryId}-optionName`],
choices,
};
}).filter((option) => option.name);
optionsNumber 배열은 모든 옵션의 고유 ID를 저장합니다. 이 배열을 매핑하여 각 옵션의 상세 항목을 구성합니다.categoryId)에 대해, 해당하는 세부사항 ID들(detailId)을 사용하여 옵션의 선택사항(choices)을 생성합니다.extra)을 포함합니다. 사용자가 입력한 값에서 이 데이터를 추출합니다.옵션과 세부사항을 동적으로 추가하거나 삭제할 수 있는 기능은 사용자 경험을 향상시키는 중요한 요소입니다.
const onAddOptionClick = () => {
const newId = Date.now();
setOptionsNumber((current) => [newId, ...current]);
setOptionsDetails((details) => ({ ...details, [newId]: [] }));
};
const onAddOptionDetailClick = (categoryId) => {
const newDetailId = Date.now();
setOptionsDetails((details) => ({
...details,
[categoryId]: [newDetailId, ...details[categoryId]],
}));
};
onAddOptionClick 함수는 새 옵션을 추가할 때 호출됩니다. 새로운 옵션 ID를 생성하고, 상태를 업데이트하여 옵션 목록에 추가합니다.onAddOptionDetailClick 함수는 특정 옵션에 새로운 세부사항을 추가할 때 사용됩니다. 이 함수는 해당 옵션 ID의 세부사항 목록에 새 항목을 추가합니다.이와 같이, React.js와 Apollo Client를 사용하여 복잡한 상태 관리와 서버와의 상호작용을 구현할 수 있습니다. GraphQL을 통해 클라이언트와 서버 간에 효율적으로 데이터를 교환하며, 동적인 웹 애플리케이션을 구축할 수 있습니다.