[REACT] - refactoring(work) - 1

IT쿠키·2024년 4월 6일

Refactoring 작업(기준)

Refactoring 이란,
겉보기 동작은 그대로 유지하고, 코드를 이해하고 수저하기 쉽게 내부 구조를 변경하는 것

하게 된 계기
1. 단순화 하여 작업이 가능 유지보수의 능률을 좀 더 올리기 위해
2. legacy code 수정 및 불필요한 코드 수정 작업 진행

case 1 - 반복되는 작업 모듈 부분

  else if (currentRecType === 'type_number') {
       return (
         <Select
           defaultValue={defaultValue}
           onChange={value => handleSelectChange(value)}
           value={selectedValue !== undefined ? selectedValue : defaultValue}
           style={{ width: 200, marginRight: 10 }}
         >
           {contentIdData
             ? contentIdData.map((section: string) => (
                 <Select.Option key={section} value={section}>
                   {section}
                 </Select.Option>
               ))
             : null}
         </Select>
       );
     }

이게 현재 기존 코드 이고 type_number에 따라서 select에 해당하는 값들이 변하게 된다. 하지만 초기에 else if를 활용하여 type_number를 계산하여 활용함

문제점
1. type_number가 늘어날수록 else if문에 대한 조건문이 많아짐
2. contentIdData 에 대한 데이터는 string[] | null 일수도 있음
3. contentIdData 에 빈 "" 스트링값이 전달되는 경우가 있음

해결책
1. javascript 메서드 include를 활용하여
-> allRectype.include(currentRecType)으로 바꾼 후 return select로 변경
2. contentIdData의 props로 전달 받을 때 contentIdData의 || undefined로 해결
3. contentIdData를 props로 받아오기 때문에 let으로 할당 해준 후 이 값을
const contentIdData = useMemo(() => {
return Array.isArray(contentId?.data)
? contentId?.data.filter(item => item !== '')
: contentId?.data ?? null;
}, [contentId?.data]);
filter와 옵셔널 체이닝을 활용하여 빈값이 아닌 경우만 데이터를 담아서 새로 할당해줌 이 부분은 비즈니스 훅 모형에서 활용함

if (
      allRecType.includes(currentRecType)
    ) {
      return (
        <Select
          placeholder={defaultValue}
          defaultValue={defaultValue}
          style={{ width: 200, marginRight: 10 }}
          value={selectedValue !== undefined ? selectedValue : defaultValue}
          onChange={(value) => handleSelectChange(value)}>
          {contentIdDataProcessed
            ? contentIdDataProcessed.map((section: string) => (
                <Select.Option key={section} value={section}>
                  {section}
                </Select.Option>
              ))
            : null}
        </Select>
      );
    } else {
      return null;
    }
  };

결과
반복적인 코드 생략 가능 좀 더 간결하게 하자면 이 allRecType.includes(currentRecType) 이 부분 을 변수명으로 선언한 후 if문 제거 후 ? 로 치환가능

case 2 - 호출 부분 단순화 및 메모제이션 컴포넌트 부분 수정 작업

  1. redux-toolkit store에서 가져오는 데이터 선언 부
  2. 메모제이션 해야 하는 값들의 통일성 부족
  3. 불필요한 로직 제거 작업
  const recType = useAppSelector(rectypeSelector);
  const demoData = useAppSelector(demoSelector);
  const xType = useAppSelector(xTypeSelector);
  const contentId = useAppSelector(contentIdSelector);
  const currentRecTypeSelectorResult = 
  const currentTab = useAppSelector(currentTabSelector);
  const randomInputContentsId = useAppSelector(randomInputContentsIdSelector);
  const { loading: recTypeLoading = false, data: recTypeResult = null } =
    recType ?? {};
  const {
    target: recommenedTargetData = null,
    results: recommenedResultsData = null,
  } = demoData?.data ?? {};

단순한 선언 호출 부 지만 이 부분 또한 좀 더 간략하게 리펙토링이 가능

문제점
1. 코드의 가독성이 떨어짐 - 각각의 useselector 선언으로 인해 가독성이 떨어짐
2. 의존성 관리 하기가 힘들어짐

  // useSelector
  const {
    recType,
    demoData,
    xType,
    contentId,
    currentRecTypeSelectorResult,
    currentTab,
    randomInputContentsId,
  } = useSelectors();
  function useSelectors() {
    return {
      recType: useAppSelector(rectypeSelector),
      demoData: useAppSelector(demoSelector),
      xType: useAppSelector(xTypeSelector),
      contentId: useAppSelector(contentIdSelector),
      currentRecTypeSelectorResult: useAppSelector(currentRecTypeSelector),
      currentTab: useAppSelector(currentTabSelector),
      randomInputContentsId: useAppSelector(randomInputContentsIdSelector),
    };
  }
  1. 코드의 가독성 향상 useSelectors 함수를 통해 여러 useAppSelector 호출을 한 곳에 모아두면 가독성이 향상됨
  2. 재사용성 증가: 특정 선택자(selector)들의 집합을 useSelectors 함수로 묶음으로써, 이 함수를 다른 컴포넌트나 훅에서 재사용할 수 있습니다. 이는 코드의 중복을 줄이고, 유지보수성을 향상시킵니다.
  3. 의존성 관리가 편안해짐 useSelectors 함수 내에서 필요한 상태를 모두 조회하므로, 컴포넌트나 훅의 의존성을 명확하게 관리할 수 있습니다. 이는 특히 프로젝트가 커지고 복잡해질 때 유용합니다.
  4. 성능 최적화 useSelectors 함수 내부에서 useAppSelector를 사용하면, 각 상태 조회 시 Redux 스토어의 상태가 변경될 때만 컴포넌트가 리렌더링되도록 최적화 되고 이로 인한 불필요한 리렌더링을 막을 수가 있음
profile
IT 삶을 사는 쿠키

0개의 댓글