구현목표

- 기존에는 사용자가 수동으로 관심학과와 개설대학을 입력해야 했던 반면,

개선된 인터페이스에서는 사용자가 관심학과를 선택하면 해당 학과를 개설한 대학의 정보를

API를 통해 자동으로 가져올 수 있도록 기능을 개선해야 했다.

 

 

백엔드 api는 수정을 할 수 없는 상황이였고, 

대신 교과정보에 대한 api와 대학교정보에 대한 api가 있었다.

 

우선 원활한 데이터전달을 위해 이 두개의 api를 부모컴포넌트로 이동한 후, 자식컴포넌트로 props로 전달해주기로했다.

 

//부모컴포넌트

const [collegeList, setCollegeList] = useState<CollegeDataType[]>([]);
  const [majorData, setMajorData] = useState<majorDataType>();

  const getMajorData = useCallback(() => {
    if (testId === undefined) return;

    getExpMajorV2(testId)
      .then((res) => {
        setMajorData({ ...res.data.majorExploration });
      })
      .catch((error) => {
        console.error("Error occurred while fetching major data:", error);
      });
  }, [testId]);

  useEffect(() => {
    getMajorData();
  }, [getMajorData]);

  //30개의 데이터만 가져오도록 설정함, 추후에 더 많은 데이터를 가져오도록 수정해야함
  const getCollegeList = (majorCode: string) => {
    getOpenUniv(1, 30, majorCode).then((res) => {
      setCollegeList(res.data.results);
    });
  };

  useEffect(() => {
    if (majorData) {
      getCollegeList(majorData.majorCode);
    }
  }, [majorData]);
  
  
  retrun (
   <HopeMajor collegeList={collegeList}/>
   )
  };

대학교 리스트와 학과정보를 저장하는 state를 만들었고,

getMajorData 함수와 getCollegeList 함수를 정의해주었다. 그리고 자식컴포넌트로 collegeList(대학정보)를 전달하였다.

 

const [universityListData, setUniversityListData] = useState<CollegeDataType[]>([]); 
const [selectedUniversityData, setSelectedUniversityData] = useState<CollegeDataType | null>(null);

 useEffect(() => {
    setUniversityListData(props.collegeList);
  }, [props.collegeList]);

 useEffect(() => {
    const updatedList = props.collegeList.map((college) => ({
      ...college,
      frontId: uuidv4(),
    }));
    setUniversityListData(updatedList);
  }, [props.collegeList]);

props으로 가져온 collegeList 데이터는 universityListData state에 넣어서 상태관리해주었다.

그런데 구현하다보니 백엔드 api로 데이터를 보낼때 필드값에 id 필드가 포함되면 에러를 반환하는걸 확인하였다.

참고로 백엔드를 수정할수는 없는 상황이였고, 임시로 id필드를 삭제하고 데이터를 보냈을때는 정상적으로 

데이터가 보내졌다. 

  //사용자가 체크박스를 클릭하여 특정 대학을 선택하거나 해제할 때마다 호출되는 함수
  const toggleItemSelection = (university: CollegeDataType) => {
    if (inputInfo1.some((item) => item.frontId === university.frontId)) {
      setInputInfo1(
        inputInfo1.filter((item) => item.frontId !== university.frontId)
      );
    } else {
      if (inputInfo1.length < 5) {
        const newMajor: hopedMajorType = {
          frontId: university.frontId,
          college: university.collegeName,
          majorHopedFor: university.majorName,
          memo: "",
          rank: inputInfo1.length + 1,
        };
        setInputInfo1([...inputInfo1, newMajor]);
      }
      setSelectedUniversityData(university);
    }
  };

하지만 지금 구현된 코드를 살펴보면 각 데이터의 고유한 값인 id값을 사용해서 데이터가 일치하는지 검증을하고 

검증된 데이터를 삭제해서 중복값도 제거하고있는데, id 값을 없애고 api데이터를 보내면 

체크박스가 또 선택이 안되는 이슈가 있었다. 

 

그래서 생각한방법이 고유한 frontId를 랜덤으로 만들어서 사용하는 방법이였다.

우선 키값필드에 frontId를 추가해주고 

  useEffect(() => {
    const updatedList = props.collegeList.map((college) => ({
      ...college,
      frontId: uuidv4(),
    }));
    setUniversityListData(updatedList);
  }, [props.collegeList]);

uuidv4라는 라이브러리를 사용하여 collegeList가 변경될때마다 추가해주는 방법이였다.

이렇게 수정하니 frontId값이 필드값에있어도 백엔드 api에서 잘 넘어가는걸 확인했다.

 

API를 직접 수정할 수 없는 상황에서, 고유한 frontId를 랜덤으로 생성하여 사용함으로써 문제를 해결했다.

API에서 요구하는 필드값의 문제를 해결하면서도, 체크박스의 중복 선택 등의 이슈를 해결하는데도 효과적이였다. 

 

 

하지만 위에서 제시한 방법은 특정한 문제를 해결하기 위한 임시 방편입니다. 현실적인 제약사항 (백엔드 API를 변경할 수 없는 상황 등)과 특정 요구사항 (중복 체크 등)을 충족하기 위해 선택한 방법입니다.

id값은 일반적으로 백엔드에서 고유하게 생성되어, 각 데이터 항목을 식별하는데 사용하는게 맞고, 프론트엔드에서 임의로 id를 생성하면 데이터 일관성을 해칠 수 있습니다. 

 

복사했습니다!