- 국가추가시 국가명이 없을때는 추가되지 않게한다.
- 국가추가시 국가명이 숫자를 포함할때도 추가되지 않게한다.
- 국가추가시 국가명이 존재할때는 새로 추가하지않는다.
- 업데이트시 존재하지 않는 국가는 알려준다.
- 업데이트시 해당 국가만 업데이트가 되게 한다.
- 국가 추가 및 업데이트시 금메달 순으로 정렬한다.
- 메달입력시 양수만 가능하게 한다.
- 메달수는 최대 2자릿수까지만 되게한다.
- 메달입력시 "02"로 입력되어도 "2"로 입력되게 한다.
- 로컬스토리지
//App.jsx const addMedalData = (newData) => { const countryExists = medalData.some( (item) => item.country === newData.country ); if (countryExists) { alert("해당 국가가 이미 존재합니다."); return; } setMedalData(sortedData); };
addMedalData
에 로직을 작성했다.//Editor.jsx const handleOnSubmit = (e) => { e.preventDefault(); if (/\d/.test(formData.country)) { alert("국가명에는 숫자를 포함할 수 없습니다."); return; } addMedalData(formData); setFormData({ country: "", gold: 0, silver: 0, bronze: 0 }); };
handleOnSubmit
에 로직을 작성했다./\d/
: 이 정규식은 0부터 9 사이의 숫자를 나타낸다..test()
: 정규식과 함께 사용되는 메서드로, 주어진 문자열에 해당 패턴이 있는지 검사하여 true 또는 false를 반환한다.//Editor.jsx const handleOnSubmit = (e) => { e.preventDefault(); if (!formData.country) { alert("국가명을 입력해주세요."); return; } addMedalData(formData); setFormData({ country: "", gold: 0, silver: 0, bronze: 0 }); };
handleOnSubmit
에 로직을 작성했다.input
값이 없을때 위와 같은 알림창을 띄워준다.//App.jsx const updateMedalData = (updatedData) => { const countryExists = medalData.some( (item) => item.country === updatedData.country ); if (!countryExists) { alert("존재하지 않는 국가입니다. 다시 확인해주세요."); return; } };
medalData
와 updatedData
의 country
값을 비교해서//App.jsx const updateMedalData = (updatedData) => { const updatedMedalData = medalData.map((item) => item.country === updatedData.country ? updatedData : item ); setMedalData(updatedMedalData); };
item.country === updatedData.country ? updatedData : item
updatedData
를 반환하고,//App.jsx // 추가시 const addMedalData = (newData) => { const sortedData = [...medalData, newData].sort((a, b) => (b.gold - a.gold); setMedalData(sortedData); }; // 업데이트시 const updateMedalData = (updatedData) => { const updatedMedalData = medalData .map((item) => item.country === updatedData.country ? updatedData : item ).sort((a, b) => (b.gold - a.gold); setMedalData(updatedMedalData); };
(출처 : 네이버 2024 파리올림픽 메달 순위)
//App.jsx const addMedalData = (newData) => { const sortedData = [...medalData, newData].sort((a, b) => { if (a.gold !== b.gold) return b.gold - a.gold; const totalA = a.gold + a.silver + a.bronze; const totalB = b.gold + b.silver + b.bronze; if (totalA !== totalB) return totalB - totalA; if (a.silver !== b.silver) return b.silver - a.silver; return b.bronze - a.bronze; }); setMedalData(sortedData); };
//EditorItem.jsx <input min="0">
처음에는 간단하게 maxLength로 하면 되겠지 싶어서 입력을 했는데,
작동이 되지 않았다. 참고문서
참고문서를 보고나서 로직을 작성해보았다.
//EditorItem.jsx <input type={type} placeholder={placeholder} name={name} value={value} min="0" onChange={onChange} onInput={ name !== "country" ? (e) => { if (e.target.value.length > e.target.maxLength) { e.target.value = e.target.value.slice( 0, e.target.maxLength ); } } : undefined } maxLength={name !== "country" ? 2 : undefined} />
prettier issue...
//Editor.jsx const handleOnChange = (e) => { const { name, value } = e.target; setFormData({ ...formData, id: new Date().getTime(), [name]: name === "country" ? value : Math.min(parseInt(value, 10)), }); };
parseInt
를 사용하여 간단히 해결했다.//App.jsx useEffect(() => { const storedMedalData = localStorage.getItem("medalDatas"); if (storedMedalData) { setMedalData(JSON.parse(storedMedalData)); } }, []); useEffect(() => { localStorage.setItem("medalDatas", JSON.stringify(medalData)); }, [medalData]);
useEffect
로 로직을 작성했다.const [medalData, setMedalData] = useState(() => { const storedMedalData = localStorage.getItem("medalDatas"); return storedMedalData ? JSON.parse(storedMedalData) : []; }); useEffect(() => { localStorage.setItem("medalDatas", JSON.stringify(medalData)); }, [medalData]);
useEffect
의 마운트 순서가 보장되지 않기 때문에,
get
방식을 초기 값으로 useState
설정해주는것이 더욱 안전하다고 하셨다.
그에 따라 로직을 수정했다.
순서에 대해 생각해본적이 없었기 때문에, 적잖은 충격이었지만
이렇게라도 알 수 있었기에 감사했다.
다음에는 절대 이런 실수를 하지말자!
vercel
로 배포했다.이렇게 과제를 모두 마무리했다.
언제나 그렇듯이 쉽지만은 않았고 처음 로직을 작성할때의 스트레스가 아직도 생생하다.
그래도 포기하지않고 해냈다.
앞으로도 어제보다 더 발전한 내가 되기위해 최선을 다하자!