2024 파리 올림픽에서 각 나라가 획득한 메달 수를 추적하는 Olympic Medal Tracker
■ 배포링크 👉 바로가기
1. 프로젝트 셋업
Vite 를 이용해서 리액트 프로젝트를 셋업하였다.
2. 기본 UI 레이아웃 작성
// App.jsx
import React from "react";
import "./App.css";
const App = () => {
return (
<div className="container">
<h1>2024 Paris Olympic</h1>
<div className="container-box">
<span>국가명</span>
<span>금메달</span>
<span>은메달</span>
<span>동메달</span>
</div>
<form>
<input />
<input />
<input />
<input />
<button>국가추가</button>
<button>업데이트</button>
</form>
<div>{/* 메달 집계 리스트가 표시될 자리 */}</div>
</div>
);
};
export default App;
3. 상태관리
국가 리스트 상태를 관리하기 위해 countries, formValues useState 를 생성하였다.
const [countries, setCountries] = useState([]);
const [formValues, setFormValues] = useState({
country: "",
gold: 0,
silver: 0,
bronze: 0,
});
4. 메달 집계 리스트 추가 및 금메달 내림차순 정렬 기능
국가명, 금메달, 은메달, 동메달 각 input 창에 값을 입력하고 국가추가 버튼을 클릭하여 입력값을 출력해준다.
추가된 국가들은 금메달 개수를 기준으로 내림차순 정렬하도록 sort 메서드를 사용하였다.
// 추가
const handleAddCountry = (event) => {
event.preventDefault();
const { country, gold, silver, bronze } = formValues;
if (!country) {
alert("국가명을 입력해주세요!");
return;
}
const newCountry = {
id: new Date().getTime(),
name: country,
gold: Number(gold),
silver: Number(silver),
bronze: Number(bronze),
};
const sortedCountry = [...countries, newCountry].sort(
(a, b) => b.gold - a.gold
);
const existCountry = countries.find(function (listCountry) {
return listCountry.name === country;
});
if (existCountry) {
alert("이미 추가된 국가입니다. 확인해주세요!");
} else {
setCountries(sortedCountry);
alert(`${newCountry.name}이 추가되었습니다!`);
}
init();
};
5. 삭제기능
filter 메서드를 이용하여 삭제 기능을 구현하였고 삭제버튼을 누르면 삭제여부를 묻는 모달창이 뜨면서 확인을 누르면 삭제가 된다.
const handleDeleteCountry = (id) => {
const deletedCountry = countries.filter((country) => country.id !== id);
if (window.confirm("삭제하시겠습니까?")) {
setCountries(deletedCountry);
return;
}
};
6. 수정(업데이트) 기능
기존에 추가된 국가와 동일한 국가의 메달 개수를 업데이트 버튼을 클릭하여 수정할 수 있다.
// ===업데이트===
const handleUpdateCountry = (event) => {
event.preventDefault();
// find => 내가 수정하려고 하는 대상 국가 찾기
const targetCountry = countries.find(function (country) {
return country.name === formValues.country;
});
if (!targetCountry) {
alert("일치하는 국가가 없습니다!");
init();
return;
}
// targetCountry의 이름과 일치하면 메달 개수를 수정
const newCountries = countries.map(function (country) {
if (country.name === targetCountry.name) {
return {
...country,
gold: formValues.gold,
silver: formValues.silver,
bronze: formValues.bronze,
};
} else { // 일치X => 그대로 내보내기
return country;
}
});
setCountries(newCountries);
alert(`${targetCountry.name}의 메달 개수가 변경되었습니다!`);
init();
};
7. input 창 초기화
상태를 변경하는 동작을 할 때마다 input 값을 비워주도록 init 함수를 만들어서 각 기능마다 넣어주었다.
const init = () => {
setFormValues({
country: "",
gold: 0,
silver: 0,
bronze: 0,
});
};
8. 메달 집계 리스트 출력 & 컴포넌트 분리
components 폴더를 생성하고 폴더안에 Countries.jsx, InputForm.jsx 파일을 생성해 App.jsx 에 작성했던 메달 집계 리스트와 국가,메달을 입력하는 inputForm 부분을 분리해줬다.
그리고 App.jsx 에서 각 컴포넌트를 import 해주고 필요한 값들을 전달했다. 각 컴포넌트에서는 props 로 값을 전달받아 사용하였다.
// App.jsx return 부분
return (
<div className="container">
<h1>2024 Paris Olympic</h1>
<InputForm
formValues={formValues}
handleChange={handleChange}
handleAddCountry={handleAddCountry}
handleUpdateCountry={handleUpdateCountry}
/>
{countries.length === 0 ? (
<p>아직 추가된 국가가 없습니다. 메달을 추적하세요!</p>
) : (
<Countries
countries={countries}
handleDeleteCountry={handleDeleteCountry}
/>
)}
</div>
);
}
9. 어려웠던 점 & 느낀점🧐
추가, 읽기, 삭제 부분은 강의에서 배웠던 내용을 바탕으로 혼자 구현을 했으나 수정하는 부분은 계속 고민하고 시도해봤지만 너무 어려웠다.
결국에는 실시간 가이드를 제공받아 업데이트 기능을 구현해 과제를 제출하였고 전체적인 로직을 혼자 처음부터 반복해서 연습해야함을 느꼈다.
리액트를 일주일 전 강의를 통해 처음으로 접하게 되었고 지금 전체적인 구조 조금이나마 알게된 지금 느끼기엔 바닐라JS 로 구현할 때보다 훨씬 편한 것 같다. 그치만 개인과제를 구현할때는 사용 방법이 너무나 익숙하지 않아서 뭐가 뭔지 파악하는 것조차 어려웠다.
얼른 익숙해지도록 반복 또 반복해서 공부하자.
'TIL' 카테고리의 다른 글
useEffect (0) | 2024.08.17 |
---|---|
React key 중복 오류 발생 (0) | 2024.08.16 |
React github page 배포 오류 해결 (0) | 2024.08.14 |
두 정수 사이의 합 (0) | 2024.08.13 |
Math.pow(), Math.sqrt() (0) | 2024.08.12 |