문제 상황
요구사항
나라 이름, 금메달, 은메달, 동메달 입력 필드를 추가하고 제출 버튼을 추가하여 폼을 완성하세요.
데이터 관점에서의 서술
1. form 태그 안에서 input 태그와 제출 버튼을 만든다.
2. 제출 버튼을 눌렀을 때 useState를 이용하여 사용자가 입력한 값을 받아온다.
3. useState를 이용하여 나라 이름, 금메달, 은메달, 동메달에 대한 모든 정보를 medalList 배열 안에 넣는다.
3. useState를 이용하여 나라 이름, 금메달, 은메달, 동메달에 대한 모든 정보를 medalList 배열 안에 넣는다.
사용자가 값을 입력할 때마다 medalList 안에 새로운 객체가 추가되어야 하는데, 그때 입력한 객체만 들어갔다.
입력한 객체만 들어가고 기존의 있던 객체는 사라지는 현상이 발생했다.
무엇이 문제였을까?
문제 원인 & 해결 과정
setMedalList(
[
{
countryName: countryName,
goldMedal: goldMedal,
silverMedal: silverMedal,
bronzeMedal: bronzeMedal,
},
]
);
3번에 대한 코드를 다음과 같이 작성하였다.
배열 안에 객체를 넣어줄 때, 기존의 medalList 값도 함께 넣어줬어야 했는데 그러지 않았다.
setMedalList(
[
...medalList,
{
countryName: countryName,
goldMedal: goldMedal,
silverMedal: silverMedal,
bronzeMedal: bronzeMedal,
},
]
);
다음과 같이 spread operator을 이용하여 기존의 medalList도 넣어줘야 한다.
그래야 배열 안에 사용자가 값을 입력할 때마다 해당 값이 모여있는 객체가 기존의 객체와 합쳐진다.
결과
Form.jsx의 전체 코드는 다음과 같다.
import React, { useState } from "react";
const Form = ({ medalList, setMedalList }) => {
const [countryName, setCountryName] = useState("");
const [goldMedal, setGoldMedal] = useState("");
const [silverMedal, setSilverMedal] = useState("");
const [bronzeMedal, setBronzeMedal] = useState("");
// 사용자가 입력한 값 업데이트
const saveCountryName = (e) => {
setCountryName(e.target.value);
};
const saveGoldMedal = (e) => {
setGoldMedal(e.target.value);
};
const saveSilverMedal = (e) => {
setSilverMedal(e.target.value);
};
const saveBronzeMedal = (e) => {
setBronzeMedal(e.target.value);
};
const submitHandler = (e) => {
e.preventDefault();
// 예외 상황 처리
if (
countryName === "" ||
goldMedal === "" ||
silverMedal === "" ||
bronzeMedal === ""
) {
return alert("값을 모두 입력하세요.");
}
// medalList state 변환
setMedalList(
[
...medalList,
{
countryName: countryName,
goldMedal: goldMedal,
silverMedal: silverMedal,
bronzeMedal: bronzeMedal,
},
].sort((a, b) => {
return b.goldMedal - a.goldMedal;
})
);
// 입력값 초기화
setCountryName("");
setGoldMedal("");
setSilverMedal("");
setBronzeMedal("");
};
return (
<form onSubmit={submitHandler}>
<div className="country">
<div>
<label htmlFor="country-input">국가명</label>
</div>
<input
type="text"
id="country-input"
placeholder="국가 입력"
value={countryName}
onChange={saveCountryName}
autoFocus
/>
</div>
<div className="gold-medal">
<div>
<label htmlFor="gold-medal-input">금메달</label>
</div>
<input
type="number"
id="gold-medal-input"
value={goldMedal}
onChange={saveGoldMedal}
/>
</div>
<div className="silver-medal">
<div>
<label htmlFor="silver-medal-input">은메달</label>
</div>
<input
type="number"
id="silver-medal-input"
value={silverMedal}
onChange={saveSilverMedal}
/>
</div>
<div className="bronze-medal">
<div>
<label htmlFor="bronze-medal-input">동메달</label>
</div>
<input
type="number"
id="bronze-medal-input"
value={bronzeMedal}
onChange={saveBronzeMedal}
/>
</div>
<button type="submit">국가 추가</button>
<button type="submit">업데이트</button>
</form>
);
};
export default Form;
반응형
'TroubleShooting' 카테고리의 다른 글
[메달 집계 관리] - return했는데도 왜 메달 리스트를 보여주는걸까 (2) | 2025.01.22 |
---|---|
[메달 집계 관리] - child in a list should have a unique "key" prop!! (0) | 2025.01.22 |
[영화 검색 사이트] - 영화 카드 사이를 누르면 오류 메시지가 뜬다?! (0) | 2025.01.17 |
[영화 검색 사이트] - Debouncing으로 실시간 검색 기능 구현하기 (0) | 2025.01.17 |
[영화 검색 사이트] - 사용자가 저장한 북마크는 어떻게 보여줄까? (1) | 2025.01.17 |