프로젝트를 만드는 중 map()함수로 인풋을 렌더링하는 작업을 했다. 버튼을 눌러서 추가하고 제거하는 동작을 만들었는데, 제거하는 과정에서 문제가 발생했다. 어떤 순서의 인풋의 제거버튼을 누르던, 가장 마지막 순서의 인풋이 제거되는 것이다.
이상해서 console.log()로 배열을 찍어보니, 콘솔에서는 제거버튼을 누른 인풋이 사라지고 나머지가 잘 출력된다.
뭐가 잘못된 것일까..
결국 이유를 찾지 못해 멘토님에게 물어보았고 답을 얻었다.
우선 윤석님 로직대로
input은index에 맞게 사라지고 있었는데value를 설정안해줘서 생긴 이슈였습니다.
value를state로 관리 안하면vdom비교 후 리렌더링할때 해당input위치에 있던input DOM의attribute를 그대로 가져가기 때문에 마지막것만 사라지는 것처럼 보였던 겁니다!
input 옵션에 value 옵션을 넣고 값에 _.function 과 _.contribution을 넣어서 가상돔과 비교 후 해당 input 위치에 잘 찾아가게 만듦으로 해결하였다.
//맵함수 안 컴포넌트
<input
onChange={(e) => {
putTextInFunc(e.target.value, index);
}}
type="text"
value={_.function}
/>
<input
onChange={(e) => {
putContInFunc(parseInt(e.target.value), index);
}}
type="number"
value={_.contribution}
/>
원래 두번째 input 옵션에 defaultValue가 있었는데, 이 상태에서 value를 넣으니까 에러가 났다.
controlled 상태와 uncontrolled상태 중 하나만 골라야 한다는 내용인데, 결국 둘 중 하나만 골라야 한다는 내용이었다. 하지만 인풋이 추가될 때 이미 처음 값이 나와서 defaultValue의 유무는 상관이 없었고, 이를 보고 defaultValue 옵션을 삭제하는 판단을 내려 문제를 해결하였다.