Cometin'

[Like Amazing Lion] Refactoring Log

2021-02-13 at Project category

Like Amazing Lion 프로젝트 리팩토링

  • 교외 동아리 멋쟁이사자처럼의 홍보용 이벤트 웹
  • Firebase와 React + TypeScript를 사용한 CSR 웹
  • Github

Log

  • Directory Structure

    • 공식 문서를 참고하여 너무 오래 고민하지 않으며 기존 형태를 유지하면서 더욱 가독성이 보기 좋게 나누도록
    • Router Directory 생성
    • App.tsx src 폴더에 위치
    • 추후 진행할 프로젝트에서는 Container-Presenter 패턴, Atomic 패턴을 이용해 볼 예정
  • Router안의 Transition Group을 이용한 Transition Router 부분을 새로운 컴포넌트를 만들어 분리

  • Loading component의 timeout 시간을 변수로 빼어 수정, 확장, 가독성 부분에서 유리하도록 수정

// before
setTimeout(() => {
  setIsLoading(true)
}, 1500)

// after
const LOADING_TIME: number = 1500
setTimeout(() => {
  setIsLoading(true)
}, LOADING_TIME)
  • assets Directory를 만들어 Theme.ts와 images 폴더를 위치

  • Nav의 오른쪽 요소들을 NavElement component로 빼둠

export interface NavInterface {
  user: firebase.default.User | null
}
  • AuthForm component의 signUp, signIn을 함수로 빼어 더욱 간결하게 작성
// before
const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault()
  try {
    if (isSignUp) {
      await authService.createUserWithEmailAndPassword(email, password)
    } else {
      await authService.signInWithEmailAndPassword(email, password)
    }
  } catch (error) {
    const { message } = error
    setErrorMsg(message)
  }
}

// after
const signUp = () => authService.createUserWithEmailAndPassword(email, password)

const signIn = () => authService.signInWithEmailAndPassword(email, password)

const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault()
  try {
    await (isSignUp ? signUp() : signIn())
  } catch (error) {
    const { message } = error
    setErrorMsg(message)
  }
}
  • 가독성을 위해 Waiting component의 다른 서비스 url 주소를 변수로 빼둠
  • target 속성과 rel 속성을 추가적으로 부여. target을 blank로 한 후 rel 속성을 noreferrer로 하지 않을 시 보안의 위협이 있다함
// before
;<a href="someurl.com">
  <Button color="primary">맛집 보기</Button>
</a>

// after
const LIKELION_FOOD_URL = 'someurl.com'
;<a target="_blank" rel="noreferrer" href={LIKELION_FOOD_URL}>
  <Button color="primary">맛집 보기</Button>
</a>
  • QuizSlider의 classList 추가 부분을 반복적으로 작성하는 부분이 적게 변환
// before
if (currentQuizNum === 0) {
  leftButton.current.classList.add('slider__hide')
} else if (currentQuizNum === maxQuizNum) {
  rightButton.current.classList.add('slider__hide')
}

// after
let modifingButton: React.MutableRefObject<any> | null = null
if (currentQuizNum === 0) {
  modifingButton = leftButton
} else if (currentQuizNum === maxQuizNum) {
  modifingButton = rightButton
}
modifingButton?.current.classList.add('slider__hide')
  • QuizProgress의 classList를 저장하는 배열을 기존 빈 배열을 선언 후 추가하는 방법에서 모두 들어가는 class명을 넣은 상태에서 조건에 따라 추가하는 방식으로 수정
// before
const tempProgress: string[] = []
for (let i = 0; i <= maxQuizNum; i++) {
  const tempElement = `progress__element ${i === currentQuizNum &&
    'progress__selected'}`
  tempProgress.push(tempElement)
}

// after
const tempProgress: string[] = Array(maxQuizNum + 1).fill('progress__element')
for (let i = 0; i <= maxQuizNum; i++) {
  if (i === currentQuizNum) {
    tempProgress[i] += ' progress__selected'
  }
}
  • 유지보수와 가독성을 위해 QuizProgress의 Class명을 변수로 선언
// before
const tempProgress: string[] = Array(maxQuizNum + 1).fill("progress__element");
for (let i = 0; i <= maxQuizNum; i++) {
    if (i === currentQuizNum) {
        tempProgress[i] += " progress__selected";
    }
}

// after
const PROGRESS_CN: string = "progress__element";
const SELECTED_PROGRESS_CN: string = " progress__selected";

...
const tempProgress: string[] = Array(maxQuizNum + 1).fill(PROGRESS_CN);

for (let i = 0; i <= maxQuizNum; i++) {
    if (i === currentQuizNum) {
        tempProgress[i] += SELECTED_PROGRESS_CN;
    }
}
  • components의 각 폴더에 있는 config 파일들을 configs 폴더에 위치

  • 각 파일들에 있었던 interface들을 types/Types.ts 파일에 위치

느낀 점

  • TypeScript의 Interface를 남용하진 않나 생각됨, Generics와 같은 추가적인 개념을 익혀야될 필요를 느낌
  • React.memo 등 최적화를 위한 방법을 더욱 공부해야될 것을 느낌
  • CSS, SCSS 등 스타일에 대한 Directory Structure 개념이 잡히지 않았다고 생각됨
  • 스타일에 대하여 우겨넣기 식으로 하지 않는 지 고민되어 CSS 또한 더 공부 해야될 것을 느낌

배운 점

  • CSR 웹의 가능성을 알게 됨
  • Firebase를 사용하여 Query, Authentication, DB등의 사용 방법을 알게 됨
  • Material UI를 사용 및 커스텀 할 수 있게 됨 (아직은 많이 부족하지만)
  • React-Transition-Group을 더욱 다채롭게 사용할 수 있게 됨
hyesungoh

Personal blog by hyesungoh.

I like to share my knowledge for those who wandering in issue.