Component의 리랜더링

devAnderson·2021년 12월 29일
0

TIL

목록 보기
8/102

What you know

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

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

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

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

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


What is aha point?

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

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

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

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

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

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


reference

how to delete objects from folder in s3

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

0개의 댓글