swsnu / swpp2019-team5

WearHouse - Your very own fashion Warehouse
3 stars 4 forks source link

[Question] Help me with re-rendering child component #30

Closed iamsungyeonjoo closed 4 years ago

iamsungyeonjoo commented 5 years ago

제가 CreateOutfit 컴포넌트 구현하다가.. Item 삭제 쪽에서 막혀서 도움을 구합니당..

제가 구현한 기본적인 삭제 방식은 다음과 같습니다. CreateOutfit 컴포넌트에 state 안에 items라는 배열이 있습니다. render함수 안에서 items 배열의 각각의 요소에 대해서 Item 컴포넌트로 매핑해줍니다. 삭제 함수를 CreateOutfit에 정의를 해줬고, 그 함수를 Item 컴포넌트의 props로 넘겨줬습니다.

image

image

그리고 Item 쪽에서는 props로 넘겨받은 item을 가지고 컴포넌트렌더를 합니다. item-delete-button을 누르면 props로 넘겨받은 delete 함수가 호출되어서, 해당 item을 CreateOutfit state에 들어가 있는 items 배열에서 삭제해주고 setState를 해주기 때문에 다시 렌더가 되어야 하는 것으로 알고 있습니다.

아래는 Item 컴포넌트 코드 입니다.

image

image

그런데 이상하게.. (스타일링이 제대로 안 되어 있어서 약간 보기 불편하실 수도 있겠지만..) image 여기서 맨 위에 있는 Top Item 삭제 버튼을 누르면 Top Item이 아니라 맨 밑에꺼가 사라집니다.. ㅠㅠ 무엇이 문제일까요?

image

feature/implement-create-outfit-component 브랜치의 commit 805d1cc4eb3141c33e7ecc5bbb190a2f5d64ddcb 을 봐주시면 될듯 하온데 ㅠㅠ 어디가 꼬인건지 어제부터 해보는데 잘 해결이 안되네용

조교님 도와주세요 ㅜㅜ @ktaebum

ktaebum commented 5 years ago

~~delete에서 비교를 할 때 object 전체를 비교를 하지 마시고 unique한 id값만 비교하면 될 것 같아요 (백엔드에서 넘어올) filter(itm => itm.id === item.id) 별다른 equality에 대한 override가 없으면 c포인터처럼 reference를 비교하게 되고 itm이 iter하면서 마지막 것만 주소가 일치해서 그것만 지우는 것 같습니다~~ 저렇게 지워도 동작은 해야합니다 단지 id로 비교해서 지우는 건 불필요한 계산을 줄일 수 있구요

또한 key에서 indexOf로 아이디 지정보단 (물론 아직 백엔드랑 연동이 안 돼서 임시겠죠?) 임시로 지정할 땐 그냥 new Date() 등으로 하시면 더 편해요. 아무라도 indexOf는 매번 iteration overhead가 있어서

ktaebum commented 5 years ago

저 문제는 아닌 것 같구요 생각해보니 reference 비교를 해도 지워져야 하네요 (이동하면서 대충봐서 죄송합니다)

아마 index를 key 값으로 사용하는 문제인 것 같아요 dynamic 하게 변할 수 있는 list에서는 index가 고정이 되지 못하기 때문에 그렇게 사용을 하시면 원치 않는 결과가 쉽게 나올 수 있습니다. 좋은 예시

또한 저렇게 iterate하면서 index를 가져오고 싶으면

items.map((item, index) => {
});

이렇게 사용하면 index와 함께 (Python에서 enumerate와 동일) iteration 할 수 있습니다

iamsungyeonjoo commented 5 years ago

조언 주셔서 감사합니다 !! 덕분에 key값을 readability가 좋게 할당하는 방식으로 바꿨습니다. 문제의 원인을 찾아보니 바뀐 props값이 Item 컴포넌트에 반영이 제대로 안됐습니다. componentDidUpdate 함수에 조건적으로 setState하도록 만들었더니 해결되었습니다. 감사합니다.