React와 DOM의 직접접근

이승훈·2022년 9월 22일
0

시행착오

목록 보기
4/23
post-thumbnail

상황

특정 HTML element를 클릭하였을 때 class 를 추가,삭제 하는 기능을 구현하고자 하였다.
Vanila Javascript 에서 흔히 사용하였듯 toggle을 사용하여 classList에 class를 추가삭제 해주었으나 이것이 패착이었다.

잘못된 접근

const sizeSelector = event => {
    const size = Number(event.nativeEvent.path[0].textContent);
    let sizeArr = selectedSize;

    sizeArr.indexOf(size) === -1
      ? sizeArr.push(size)
      : (sizeArr = sizeArr.filter(element => element !== size));

    event.target.className === ''
      ? event.nativeEvent.path[1].classList.toggle('selected')
      : event.target.classList.toggle('selected');

    setSelectedSize([...sizeArr]);
  };

위의 함수는 특정 element의 class list를 조작하기 위해 javascript에서 직접 DOM 요소에 접근한다.
리액트는 가상 DOM을 사용하여 페이지의 변화시 최소한의 HTML element만 변경하도록 해준다.
이것은 리액트의 장점이고 리액트로 개발을 진행함에 있어서 이 장점들을 이용해야한다.
이러한 관점에서 보았을 때 위의 코드는 직접 HTML element에 접근하기 때문에 리액트의 장점을 살리지 못한 코드라고 할 수 있다.

개선 후

const sizeSelector = event => {
    const size = Number(event.target.title);
    let sizeArr = [...selectedSize];

    sizeArr.indexOf(size) === -1
      ? sizeArr.push(size)
      : (sizeArr = sizeArr.filter(element => element !== size));

    setIsChecked(prev => !prev);
    setSelectedSize(sizeArr);
  };
  return (
    <div
      className={`sizeNumber ${isChecked ? 'selected' : ''}`}
      onClick={sizeSelector}
      title={size}
    >
      <div>{size}</div>
    </div>
  );
}

위의 함수는 리액트가 HTML element를 직접 생성해서 넘겨준다는 특성 그리고 그 안에서 javascript 로직을 사용할 수 있다는 특성을 잘 활용하였다.
위처럼 DOM에 직접 접근하지 않고 내가 class 를 직접 추가해준 후 해당 HTML element를 돌려주면 된다.

생각

리액트를 사용하여 개발을 하고 있음에도 리액트의 장점을 최대한 살리지 못하는것은 활과 화살을 쥐고있지만
활로 대상을 직접 때리는것과 다르지 않다.
그저 기능을 구현함에만 집착하지 말고 어떻게 하면 조금 더 효율적이고 최대한의 성능을 발현시킬수 있는지 고민하도록 하자.

profile
Beyond the wall

0개의 댓글