✔︎ FAQ 질문 추가 시 타이틀 리셋 버그 디버깅
현상 : '자주 묻는 질문 이름'에 Title를 입력하고, 질문 추가하기 버튼을 클릭하면 타이틀이 예상치 않게 리셋되어 저장하기 버튼이 비활성화 상태로 변경되는 문제가 발생했습니다.


디버깅 과정 : useEffect 훅을 활용하여 Title먼저 입력하고, 질문 추가 후 title 상태값이 잘 들어오는지 확인해보니 빈 값이 나와서, 질문 추가하기 버튼 핸들러 함수를 자세히 살펴보았습니다. 이때 질문 & 답변 입력 필드를 초기화하는 과정에서 reset()을 사용했는데, 이 reset()함수는 useInputs 커스텀 훅을 사용하여 state를 {}객체로 관리하는데, 이때 객체 안에 들어 있는 모든 state를 초기화하기 때문에 발생한 문제였습니다.
const [{ title, question, answer }, onChange, reset] = useInputs({
title: selectedBlock?.title || '',
question: '',
answer: '',
});
// Title 상태 디버깅
useEffect(() => {
console.log('title', title);
},[title]);
// "질문 추가하기" 버튼 클릭 시 실행되는 함수
const handleAddFaqButtonClick = () => {
// 새로운 FAQ 객체 생성
const newFaq = { faqId: nanoid(), question, answer };
// faqList 상태 업데이트
setFaqList((prev) => [...prev, newFaq]);
// 입력 필드 초기화
reset()
};
해결 : 따라서 질문 & 답변 입력 필드만 초기화하여 사용자 경험을 향상시키고자 각각 이벤트에 접근하여 value값을 빈 값으로 변경해주는 로직으로 수정하여 버그를 해결하였습니다.
// 입력 필드 초기화
onChange({ target: { name: 'question', value: '' } });
onChange({ target: { name: 'answer', value: '' } });
✔︎ 다중 이미지 업로드 시 1개의 이미지만 업로드되는 버그 디버깅
현상 : input필드에 multiple 속성을 추가하고 이미지를 업로드할 때, 이미지가 하나만 업로드되는 문제가 발생했습니다.


디버깅 과정 : 버그를 해결하기 위해 먼저 JSX 코드에서 input 필드의 id와 label 필드의 htmlFor이 일치하는지 확인했습니다. 그 후, 삼항연산자를 사용한 label 필드에서 중복된 htmlFor="file"을 제거하여 이미지를 여러 개 업로드할 수 있게 했습니다. 이로써 input요소와 label요소의 연결이 꼬였던 문제를 해결하였습니다. 그러나 미리보기 화면에는 여전히 1개의 이미지만 나타났기 때문에 이미지 업로드 함수를 자세히 살펴보았습니다. 이전 코드에서는 항상 첫 번째 파일만을 업로드하도록 작성되어 있어 발생한 문제였습니다.
// 이전 코드
// 이미지 업로드 시 실행되는 함수
const handleImageChange = async (e) => {
const selectedFiles = e.target.files;
if (uploadedImages.length >= MAX_UPLOADS) {
// 이미지 개수가 최대 개수에 도달한 경우 모달 창을 띄워 알림 표시
Modal.info({
content: `이미지는 최대 ${MAX_UPLOADS}장까지 첨부할 수 있어요.`,
});
return;
}
// 수정하기 전!!!
const file = e.target.files[0];
if (file) {
setUploadedImages([...uploadedImages, file]);
}
};
return (
{uploadedImages.length >= MAX_UPLOADS ? (
<>
<div onClick={handleImageChange}>
{/* 수정하기 전!!! */}
<label htmlFor="imageInput">
<CameraOutlined />
<span>{`${uploadedImages.length} / ${MAX_UPLOADS}`}</span>
</label>
</div>
</>
) : (
<>
<label htmlFor="file">
<CameraOutlined />
<span>{`${uploadedImages.length} / ${MAX_UPLOADS}`}</span>
</label>
<input
id="file"
type="file"
accept="image/*"
multiple // 다중 선택
onChange={handleImageChange}
/>
</>
)}
);
};
해결 : 이후 코드에서는 선택한 모든 이미지를 새로운 배열로 만들어 업로드 이미지 배열에 추가하는 방식으로 수정하여 버그를 해결하였습니다.
// 이후 코드
// 이미지 업로드 시 실행되는 함수
const handleImageChange = async (e) => {
const selectedFiles = e.target.files;
if (uploadedImages.length >= MAX_UPLOADS) {
// 이미지 개수가 최대 개수에 도달한 경우 모달 창을 띄워 알림 표시
Modal.info({
content: `이미지는 최대 ${MAX_UPLOADS}장까지 첨부할 수 있어요.`,
});
return;
}
// 수정한 부분!!!
// 선택한 이미지들을 새로운 배열로 만들어 업로드 이미지 배열에 합침
const newImages = [...uploadedImages, ...Array.from(selectedFiles)];
setUploadedImages(newImages);
};
return (
{uploadedImages.length >= MAX_UPLOADS ? (
<>
<div onClick={handleImageChange}>
{/* 수정한 부분!!! */}
<label>
<CameraOutlined />
<span>{`${uploadedImages.length} / ${MAX_UPLOADS}`}</span>
</label>
</div>
</>
) : (
<>
<label htmlFor="file">
<CameraOutlined />
<span>{`${uploadedImages.length} / ${MAX_UPLOADS}`}</span>
</label>
<input
id="file"
type="file"
accept="image/*"
multiple // 다중 선택
onChange={handleImageChange}
/>
</>
)}
);
};

'React' 카테고리의 다른 글
| 효율적인 이미지 관리를 위한 코드 리팩토링 (2) | 2023.09.22 |
|---|---|
| 데이터 관리: Firebase vs Supabase 비교 (2) | 2023.09.22 |
| Lodash의 Deboucing 활용 - 버튼 중복 클릭 방지 (2) | 2023.09.18 |
| React) 불변성이란? (4) | 2023.06.14 |