안녕하세요. 이승호 전문가입니다.
쥬스탄드 스토어를 활용해 다중 모달을 관리할 때 모달 리스트 배열 전체를 구독하게 되면, 모달이 하나만 추가되거나 삭제되어도 배열의 참조 값이 변하기 때문에 현재 열려 있는 다른 모달들까지 전부 재렌더링되는 깜빡임 현상이 발생합니다.
현재 스토어 구조를 그대로 유지하면서 불필요한 재렌더링을 막고 깜빡임을 해결할 수 있는 가장 현실적이고 효율적인 방법들을 소개해 드리겠습니다.
첫 번째로 추천하는 방법은 스토어를 구독할 때 셀렉터를 쪼개서 가져오는 방식입니다.
기존에는 컴포넌트에서 모달 리스트 배열 전체를 통째로 가져와 맵 함수를 돌렸을 텐데, 모달을 화면에 뿌려주는 모달 컨테이너 컴포넌트와 개별 모달 컴포넌트의 역할을 철저히 분리해야 합니다.
최상위 모달 컨테이너 컴포넌트에서는 쥬스탄드 스토어에서 모달들의 고유한 아이디 값이나 패스 목록만 포함된 단순 배열만 구독하도록 합니다. 그리고 맵 함수를 돌릴 때 개별 모달 컴포넌트에게 아이디 값만 프롭스로 넘겨줍니다.
각각의 개별 모달 컴포넌트 내부에서는 넘겨받은 아이디 값을 가지고 쥬스탄드 스토어에서 자기 자신의 파람스나 데이터만 쏙 골라서 구독하도록 코드를 수정합니다. 이렇게 하면 새로운 모달이 추가되어도 기존에 열려 있던 모달 컴포넌트들은 자기가 감시하고 있는 데이터가 변하지 않았기 때문에 재렌더링을 수행하지 않고 그 자리에 가만히 유지됩니다.
두 번째 방법은 쥬스탄드에서 제공하는 얕은 비교 함수인 샬로우를 활용하는 것입니다.
만약 모달 배열의 주소값은 바뀌더라도 내부의 실질적인 컨텐츠 데이터가 변하지 않았다면 재렌더링을 건너뛰도록 제어할 수 있습니다. 쥬스탄드 스토어에서 데이터를 호출할 때 두 번째 인자로 샬로우 함수를 넣어주면, 리액트가 배열 내부의 값들을 하나씩 비교하여 실제로 내용물이 바뀌었을 때만 컴포넌트를 다시 그립니다. 이 방법은 기존 코드를 크게 고치지 않고 한 줄의 코드 추가만으로도 어느 정도 렌더링 최적화 효과를 볼 수 있습니다.
세 번째로 리액트의 내장 기능인 유즈메모나 리액트 닷 메모를 적극적으로 결합하는 방법이 있습니다.
개별 모달 컴포넌트들을 리액트 닷 메모로 감싸주면 프롭스로 전달되는 값들이 변하지 않는 한 부모 컴포넌트인 모달 컨테이너가 스토어 변화로 인해 재렌더링되더라도 자식 모달들은 이전에 그려둔 화면을 그대로 재사용합니다. 이때 주의할 점은 맵 함수를 돌릴 때 주는 키 값으로 배열의 인덱스를 쓰면 안 되고, 반드시 모달의 고유한 고유 아이디나 패스 명을 지정해 주어야 리액트가 어떤 모달이 그대로 유지되어야 하는지 정확히 인지합니다.
이론적으로 스토어를 바꾸지 않고도 컴포넌트의 구조적 분리와 개별 구독 방식을 도입하면 깜빡임 현상을 완벽하게 잡아낼 수 있습니다. 핵심은 모달 리스트 전체를 한 곳에서 다 들여다보게 하지 말고, 껍데기만 리스트를 보게 한 뒤 실제 알맹이들은 자기 데이터만 바라보도록 파편화하는 것임을 기억하시면 좋겠습니다.