Tab Elements 관리 및 상태 유지에 대한 고민

박종대·2022년 10월 13일
0

Convi

목록 보기
5/9

Tab Element의 출력

현재 선택된 Tab에 대한 Tab Element를 출력하는 방식에 대해서도 Tab은 많이 달라질 수 있습니다. 현재 구현 해놓은 방식은 다음과 같습니다.

	props.children[selectedTab]

Tab의 하위 컴포넌트로 주어진 TabElements 배열에서 선택된 탭의 index 컴포넌트'만' DOM에 렌더링 됩니다. 선택되지 않은 탭의 컴포넌트들은 DOM에 렌더링 되지 않습니다.

해당 방식에는 문제점이 존재합니다.

SQL1 탭에서 작업을 한 후 SQL2 탭으로 넘어가면 SQL1 탭에서 작업한 내용은 사라지게 됩니다. DOM Tree에 새로 렌더링 되기 때문입니다.

하지만 일반적으로 에디터 프로그램을 사용할 때 탭을 한번 이동했다고 작업 내용이 모두 사라지는 것은 사용자 입장에서 억울합니다. 이럴 때는 반드시 해당 문제를 해결해야만 했습니다.

문제를 해결하기 위해서는 선택되지 않은 tab의 elements들도 DOM Tree에서 들고 있어야 합니다. 혹은 콘텐츠 컴포넌트들의 상태를 브라우저 저장소에 저장하는 방법도 있겠지만 저는 전자로 해결하도록 하겠습니다.

DOM Tree에서는 존재하지만 화면에 보이지 않도록 할 수 있는 display: none이나 visibility: hidden css를 사용하면 해결할 수 있습니다. 참고로 전자는 DOM Tree까지만 들고 있고 렌더링은 하지 않습니다. 후자는 DOM의 렌더 트리에 까지 가지고 가서 영역은 차지하게 된다는 차이점이 있습니다.

children[selectedTab] // DOM Tree에는 선택된 Element만!

children.map((child, index) => (
		<span
			key={`${child.props.title}-${index * 1}`}
			css={css`
				display: ${selected === index ? 'inline' : 'none'};
			`}
		>
			{child}
		</span> // DOM Tree에는 모든 elements가 존재!

모든 element들을 DOM Tree에서 항상 들고 있으면 성능 측면에서의 문제는?

그래서 해당 구조는 tab이 많이 생성될 수 있을 때 적합한 구조는 아닙니다.

따라서 사용하는 Tab의 기능에 따라 구조를 사용자가 적절히 변경할 수 있도록 Props를 추가하겠습니다.

forceRender: boolean

forceRender가 false일 경우 모든 element들을 DOM Tree에서 항상 들고 있음. element들의 상태를 유지할 수 있지만 tab이 많이 생성될 때 적합한 구조는 아님.

그럼 forceRender props를 실제로 테스트 해보도록 하겠습니다.

forceRender를 true로 넘겨주었을 경우 모든 element들을 DOM Tree에서 유지하지 않기 때문에 input의 text state가 유지되지 않는 것을 확인할 수 있습니다.

반면 forceRender를 false로 넘겨주었을 경우 모든 element들을 DOM Tree에서 유지하고 있기 때문에 input의 text state가 유지됨을 확인할 수 있습니다.

profile
Frontend Developer

0개의 댓글