쿠팡이츠 음식 CRUD 구현하기

shooting star·2024년 5월 11일
post-thumbnail

들어가며

이번 글에서 React.js, GraphQL, Apollo를 활용하여 음식 추가, 수정, 삭제 기능을 개발하는 과정을 세부적으로 소개하겠습니다. 이 포스팅은 코드의 핵심 부분을 중심으로 기술적인 내용을 깊이 있게 다루며, 개발자들이 쉽게 이해할 수 있도록 설명합니다.

1. 음식 추가 기능 구현

음식을 추가하는 AddDish 컴포넌트는 Apollo Client의 useMutation 훅을 사용하여 GraphQL 서버에 데이터를 전송합니다. 이 과정에서 다음과 같은 GraphQL 뮤테이션을 사용합니다:

mutation createDish($input: CreateDishInput!) {
  createDish(input: $input) {
    ok
    error
  }
}

위 뮤테이션은 CreateDishInput 타입의 입력값을 필요로 하며, 새로운 음식을 생성하는 API를 호출합니다.

주요 React 컴포넌트 코드:

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을 호출하여 서버에 데이터를 전송합니다. 성공적으로 데이터가 추가되면 사용자는 이전 페이지로 돌아갑니다.

2. 음식 수정 및 삭제 기능 구현

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 함수가 호출되어 해당 음식을 삭제합니다.

3. 동적 옵션 관리

음식 추가 기능에서 다양한 옵션과 세부사항을 관리합니다. optionsObject는 각 옵션의 고유 ID(categoryId)를 매핑하여 옵션과 선택사항(choices)을 생성합니다. 옵션 추가 및 삭제 이벤트는 동적으로 처리되며, onAddOptionClickonAddOptionDetailClick 함수를 통해 새 옵션과 세부사항을 상태에 추가합니다.

음식 추가 기능의 구현 상세 설명

동적 옵션 관리

음식 추가 기능에서는 여러 옵션과 그 세부사항을 관리할 수 있어야 합니다. 각 옵션은 사용자에게 추가 선택사항을 제공합니다.

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);
  1. optionsNumber 배열은 모든 옵션의 고유 ID를 저장합니다. 이 배열을 매핑하여 각 옵션의 상세 항목을 구성합니다.
  2. 각 옵션 ID(categoryId)에 대해, 해당하는 세부사항 ID들(detailId)을 사용하여 옵션의 선택사항(choices)을 생성합니다.
  3. 선택사항은 이름과 추가 비용(extra)을 포함합니다. 사용자가 입력한 값에서 이 데이터를 추출합니다.
  4. 옵션 이름이 없는 경우는 제외하고, 최종적으로 옵션 객체를 생성합니다.

옵션 추가 및 삭제 이벤트 처리

옵션과 세부사항을 동적으로 추가하거나 삭제할 수 있는 기능은 사용자 경험을 향상시키는 중요한 요소입니다.

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을 통해 클라이언트와 서버 간에 효율적으로 데이터를 교환하며, 동적인 웹 애플리케이션을 구축할 수 있습니다.

0개의 댓글