React 인라인 스타일링에 객체를 넣으면 안되는 이유

리액트에서 인라인 스타일링을 할 때 보통 아래처럼 코드를 작성한다.

const MyApp = () => {
  return (
    <div style={{ marginTop: 10 }}>
      Hi there!
      <button>Button</button>
    </div>
  );
};

하지만 위처럼 코드를 작성하게 되면 MyApp이 매번 렌더링 될 때마다 객체인 { marginTop: 10 } 이 재정의되며, div 태그에 속하는 하위 요소들까지 다시 생성한다. 작성하는 입장에서는 똑같은 코드 같아 보여도, 자바스크립트는 이를 다르게 인식하는 것이다.

reference_type_object

객체는 새로 생성될 때마다 레퍼런스 값이 생성되기 때문에 위처럼 언뜻 봤을때는 같아 보여도 실제로 비교하면 다른 값이라는 결과가 나오게 된다. 위 그림처럼 {} 객체를 생성하고 비교하면 false가 리턴되지만, a라는 변수에 객체를 넣고 a와 a를 비교하면 true가 리턴된다. 이 원리를 리액트 인라인 스타일링에도 적용할 수 있다.

const myAppStyle = { marginTop: 10 };

const MyApp = () => {
  return (
    <div style={myAppStyle}>
      Hi there!
      <button>Button</button>
    </div>
  );
};

이렇게 처리하면 컴포넌트가 리렌더링 될 때 매번 인라인 스타일링의 값이 달라지지 않기 때문에 최적화를 할 수 있다. 이는 비단 인라인 스타일링에만 적용되는 것이 아니라 이벤트 리스너에 따른 이벤트 핸들러 콜백 처리와도 연관된다. 리액트 훅스에서 useCallback을 사용하는 이유도 컴포넌트가 렌더 될 때마다 함수를 재생성하기 떄문에 함수를 재생성하는 조건을 받아서 이에 따르는 비효율을 최소화하기 위함이다.(해당 내용은 추후에 포스트로 작성하겠다.)

물론 위와 같이 짤막한 코드나 간단한 인라인 스타일링의 경우까지 변수 지정을 해서 매번 정의해줄 필요는 없다. 리액트는 충분히 빠르기 때문에 매번 코딩을 할 때마다 리렌더링과 최적화 그리고 코드치는 속도의 밸런스를 잘 조율해가며 개발해야겠다.