[TIL] 0312

yoon Y·2022년 3월 12일
0

2022 - TIL

목록 보기
56/109

데브매칭 과제 테스트

평소 사용하던 class기반 컴포넌트 템플릿이 부모state변경 시에 모든 컴포넌트가 재렌더링 되는 구조였는데, 이번 과제는 keyup이벤트를 사용해야했고, input값이 변경될 때마다 input도 재렌더링이 되는 문제점이 생겼다. 결국 템플릿 사용을 포기하고 특정 자식만 재렌더링 되도록 코드를 수정하느라
쓸데없는 시간이 들어서 기능을 많이 구현하지 못했다.. 클래스 확장의 편리함과 부분 렌더링을 모두 가져가는 컴포넌트 구조를 많이 고민해봤지만 답이 안나와서 전부 재렌더링되지만 편리한 방법을 가져갔는데
걸림돌이 되었다.. 좀 더 고민해볼걸 그랬다

테스트를 마치고 어떻게 하면 두 기능을 다 가져갈지 이것저것 시도해봤는데 결국 방법을 생각해냈다

  1. class 내부에 프로퍼티를 선언해준다
    • 꼭 선언해줘야 메소드에서 사용할 수 있다(나중에 할당하더라도)
    • constructor함수를 포함해서 모든 메소드 실행 전에 먼저 선언된다
export default class ProductDetailPage extends Component {
  $selectedOptions;
  $select;
  ...
  1. 템플릿 리터럴 렌더링 후 mounted함수에서 자식 컴포넌트들을 생성하는데 1번에서 만들어둔 프로퍼티에 할당한다
    • 이후에 다른 메소드에서도 사용할 수 있다
  createSelectedOptionsComponent() {
    const $selectedOptions = this.$target.querySelector(
      '.ProductDetail__selectedOptions',
    );
    const { productData, selectedOption } = this.state;
    const { productPrice } = productData;

    this.$selectedOptions = new SelectedOptions($selectedOptions, {
      productPrice,
      selectedOption,
      onChange: this.handleChangeInput.bind(this),
      onSubmit: this.handleSubmit.bind(this),
    });
  }

  mounted() {
    if (!this.state) {
      return;
    }
    this.createSelectComponent();
    this.createSelectedOptionsComponent();
  }
  1. 특정 자식 컴포넌트만 렌더링시키는 reRender메소드를 만들어서 프로퍼티에 저장된 자식 컴포넌트의 setState함수를 꺼내서 실행시킨다
  reRender() {
    const { selectedOption } = this.state;

    this.$selectedOptions.setState({
      selectedOption,
    });
  }
  • setState시에 2번째 인자에 따라 모든 돔을 재렌더링 시킬 지, 특정 돔만 렌더링 시킬 지 지정할 수 있게 수정했다
// template/Component.js

  render() {
    this.$target.innerHTML = this.template();
    this.mounted();
  }

  reRender() {
   // 특정 자식 컴포넌트만 렌더링 시키는 코드(setState꺼내서 실행)
  }

  setState(newState, reRender = false) {
    this.state = { ...this.state, ...newState };
    reRender ? this.reRender() : this.render();
  }

동적으로 바뀌는 돔은 컴포넌트로, 바뀌지 않는 돔은 template literal로 작성하면된다!
이 방법이면 클래스 확장의 편리함과 부분 렌더링을 모두 가져갈 수 있다!
클래스에 대한 이해가 부족해서 별 거 아닌데 많이 해멘 것 같다..
메소드에서 변수를 쓰려면 무조건 전역 프로퍼티를 먼저 선언해줘야한다는 건 알았는데
construtor함수 안에서만 가능한 줄 알았다..
이번 과제가 공개되면 3시간 잡고 다시 풀어봐야겠다.


WaffleCard Refactoring

context api 학습

provider: 값 제공(생성)
hook: 값을 받아서 가공 후 반환, 컨텍스트 받는 처리해주어 컴포넌트에서 간단하게 사용할 수 있게 함
component: hook에서 반환한 값을 받아서 렌더링

CardList animation

모달 창 오픈 시 애니메이션 중지
modalProvider에서 모달 열리고 닫히는 isOpen상태값 추가,
cardList 컴포넌트에 불러와 useEfferct에 isOpen상태를 의존으로 걸어주어
ture일 경우 애니메이션 재생, false일 경우 중지 되게 구현

  useEffect(() => {
    isOpen ? setIsPlayMove(false) : setIsPlayMove(true);
  }, [isOpen]);

Tab이 바뀔 때마다 animation새로 실행되도록 구현
→ Tab의 type을 의존으로 걸어 준 후 스크롤을 가장 앞으로 당겼다
각 tab마다 스크롤을 기억해놓고 싶지만 같은 dom을 쓰기 때문에 불가능할 것 같은데 더 생각해봐야겠다

  const handleClickFrontButton = useCallback(() => {
    if (containerDom instanceof Element) {
      containerDom.scrollLeft = 0;
      setIsPlayMove(true);
    }
  }, [containerDom]);

  useEffect(() => {
    handleClickFrontButton();
  }, [handleClickFrontButton, resetDep]); // resetDep === tab의 type

custom hook에 typescript사용
카드 리스트 애니메이션 관련 로직들을 hook으로 분리했다
custom hook사용 시 리턴 타입을 지정해줘야 한다

type ReturnTypes = [() => void, () => void, (on: boolean) => void];
profile
#프론트엔드

0개의 댓글