brunch

You can make anything
by writing

C.S.Lewis

by zwoo Dec 05. 2021

Drawer Navigator에 삽입한 이미지 변경하기

 key  를 통한 이미지 리렌더


결론부터 말하자면, 리액트 컴포넌트를 강제로 언마운트시키고 리렌더를 시키고 싶다면 변경할 컴포넌트에 key 속성을 부여하고 매번 바꾸어주는 방법을 사용할 수 있다. 좀더 엄밀히 말하자면 기존 컴포넌트 인스턴스를 지우고 새로 만든 컴포넌트를 마운트시키는 방법이다.



프로필 이미지 변경 버그


CreateDrawerNavigator API  이용해 만든 사이드메뉴 내비게이터 상에 사용자의 프로필 이미지를 표시하는 경우에, 사용자가 프로필 스크린으로 가서 이미지를 변경하고 돌아오면 변경된 이미지가 사이드메뉴에서 제대로 표시되지 않는 현상을 발견했다. 원인을 아직도 찾지 못했다. 바뀐 이미지 URL  서버에서 정상적으로 보내주는 것을 확인하였고, 디버깅 콘솔에서도 즉시 바뀐 URL  출력되는 것을 확인하였다. 답답한 것은, 사이드메뉴에서는 새로 바뀐 이미지도, 이전 이미지도 둘다 보이지 않고 그저  영역이 하얗게 표시될 뿐이라는 점이다. state, props 업데이트를 이렇게 저렇게 시켜보았지만 소용이 없었다. 모든 부가적인 코드라인을 제거하고 Image 태그만 남겨도 동일한 현상이 발생했다.


결국, 새로 바뀐 URL이 적용될 수 있도록 강제로 언마운트 시킨 후 리렌더 조치를 하기로 하였다.



Key 속성을 통한 강제 업데이트


리액트 공식문서에 따르면, 리액트 컴포넌트는 고유의 Key 속성을 부여받음으로써 해당 항목을 식별하고, Key 가 이전과 달라지면 새로운 컴포넌트 인스턴스를 생성한다. Key 속성에 대해서는 배열의 각 항목에 고유한 값을 부여하기 위한 쓰임새만 알고 있었는데, 이번에 컴포넌트 강제 업데이트 방법을 고민하면서 새롭게 알게 된 내용이다.


그렇다면 어떻게 Key 를 변경시켜줄까? 다양한 방법이 있을 수 있겠지만, 나는 해당 컴포넌트의 프라이빗 변수로 componentKey 를 선언하고, constructor 에서 null 로 초기화한 후 props로 받은 이미지 url 이 변경될 때마다 componentKey가 업데이트되도록 했다. 현재시각을 componentKey로 준 것은 두가지 이유가 있는데, 첫째는 현재시각은 매초 달라지므로 매 호출시점마다 고유성이 보장되고, 둘째로 아무 의미 없는 값보다는 어느 정도 의미가 있는 값을 Key 로 주고 싶었기 때문이다. (하지만 의미있는 값을 찾기 위해 이미지 url 을 파싱하는 과정을 만드는 것은 지나치다는 생각이 들었다)


https://gist.github.com/yeonwooz/45c6a2d22c2d438fda02a529f5d12c0f




하지만 도대체 왜일까


여전히 알 수가 없는 이 이미지 렌더 오류는 과연 리액트 네비게이션 라이브러리가 가진 버그일까, 아니면 내가 props 와 state 를 전달하는 데에 문제가 있는 코드를 작성했기 때문일까? 원인을 꼭 찾고 싶다. 접근방식을 다른 관점에서 고민해보아야 할 것 같다.









People vector created by pikisuperstar - www.freepik.com


참고링크


- 리스트와 키

- Fully uncontrolled component with a key

- 4 methods to force a re-render in React

- Understanding React componentDidMount and how it works 

- https://stackoverflow.com/questions/55236953/unmount-or-re-render-screen-in-drawer-navigator

- https://stackoverflow.com/questions/35792275/how-to-force-remounting-on-react-components

- React Derived State 다시 보기

매거진의 이전글 [DATA TIL] 0과 1의 체계에서 음수 표현하기
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari