Component의 리랜더링

devAnderson·2021년 12월 29일
0

TIL

목록 보기
8/105

What you know

  • 컴포넌트 제작 중, 이미지의 내용물을 변경하는 과정에서 리랜더링을 기대하였으나 의도대로 변경되지 않았다

  • 알기로는, 리엑트에서 리랜더링이 되기 위한 가장 큰 베이스조건은

    1. 부모 컴포넌트가 리랜더링 된다
    2. prop의 내용물이 변경된다
    3. 내부의 상태가 변경된다
  • 현재 aws의 데이터베이스 부담을 줄이기 위해, 파일 이름을 특정 유저의 아이디로 고정하고, 매번 프로필을 업데이트 할 때마다 그 기존 사진을 삭제하고 다시 유저 아이디로 이미지를 저장하여 그 저장 url을 응답으로 받아 img 의 src에 담아두는 로직을 짜두었었다.

스크린샷 2021-12-10 오전 11 41 59

  • 하지만, 이미지의 내용이 달라지더라도 리엑트는 리 랜더링을 해주지 않았다
  • 임시방편으로 window.location.reload()를 이용하여 새로고침을 했지만, 도큐먼트가 새로 만들어지면서 깜빡거리는 모습은 정말로 보기가 안좋았다.

이미지가 변경되는 것을 확인하려면 새로고침을 해야만 했다...


What is aha point?

  • 그러다가, 나는 중요한 사실을 놓쳤다는 것을 알게되었다.
  • 리엑트는 react dom이라는 가상 돔을 만든 후, 실제 html이 파싱되면서 만들어진 DOM 객체에 해당 내용을 반영하기 전에 우선적으로 이 가상 돔을 형성하여 기존 값과 차이가 나는 부분을 확인한다.
  • 문제는 이때의 비교를 shallow 비교를 한다는 점인데, shallow 비교란 말 그대로 가장 겉의 부분의 일치성을 훑듯이 확인하는 방법이다.
  • 다시말해, scalar value(number, string)은 일치를 확인하고, 객체의 경우는 해당 객체의 메모리 주소인 reference 를 체크하여 서로 같은지를 확인한다.
  • 그렇다면, 지금 내상황을 돌아보았다.
  • 리엑트 입장에서 prop으로 이미지 주소가 들어왔는데, 이 이미지주소는 여전히 똑같은 이미지 주소였던것이다
  • 즉, 리엑트는 판단하기를 리랜더링이 할 필요가 없다고 생각하고 랜더링을 해주지 않았던 것이다.

거듭, 밑의 주소는 아무리 실제 내용물이 다르더라도 리엑트 입장에서는 똑같은 주소 string에 불과했었다.

스크린샷 2021-12-10 오전 11 41 59

  • 이런 문제를 해결하기 위해, s3 버킷에 user id로 새로운 버킷폴더를 만들고, 그 안에 내용물을 프로필 사진의 변경 요청이 올 때마다 비우고 다시 채워넣고, 그 떄에는 파일 이름을 랜덤한 형태로 만들어 일치하지 않도록 로직을 짜두었다.

  • 절차를 위해 필요했던 핵심적인 함수는 aws-sdk 패키지에서 제공하는 메소드인 s3.listObjects였다.

  • 특이하게도, s3에 저장되는 것은 모조리 객체이고, 설령 폴더처럼 보일지라도 그건 그냥 객체에 연결되어 있는 또다른 객체라는 사실에 한번 놀랐다.

  • 그래서 폴더마냥 보이고 있는 이 트리를 건드려면 일단 s3.listObjects를 이용하여 특정 객체와 연결된 객체들의 리스트를 받아 조건에 따라 지우는 방향으로 진행해야 했다

스크린샷 2021-12-10 오후 10 26 25


reference

how to delete objects from folder in s3

profile
자라나라 프론트엔드 개발새싹!

0개의 댓글