- 개인과제 회고 - 올림픽 메달 기록2025년 01월 22일
- redpome
- 작성자
- 2025.01.22.:01
리액트를 위한 개인과제로 국가별 올림픽 메달을 입력받고 리스트에 등록하는 과제를 하고있다.
리팩토링을 하기 위해 코드를 나누기 전의 코드이다.
import { useState } from "react"; import "./App.css"; import Button from "@mui/material/Button"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import Paper from "@mui/material/Paper"; // import UserForm from "./UserForm"; const App = () => { //createData는 데이터를 받아 객체로 반환 const [rows, setRows] = useState([ { id: 1, country: "한국", gold: 10, silver: 5, copper: 3, }, ]); const [country, setCountry] = useState(""); const [goldMedal, setGoldMedal] = useState(0); const [silverMedal, setSilverMedal] = useState(0); const [copperMedal, setCopperMedal] = useState(0); const addMedalInfo = (e) => { e.preventDefault(); const checkCountry = rows.some((row) => row.country === country); if (checkCountry) { alert("이미 존재하는 국가입니다"); return; } const newRow = { id: Date.now(), country, gold: goldMedal, silver: silverMedal, copper: copperMedal, }; setRows([...rows, newRow]); console.log(rows); }; const deleteMedalInfo = (id) => { setRows(rows.filter((element) => element.id !== id)); }; const updateMedalInfo = (e) => { e.preventDefault(); const checkCountry = rows.some((row) => row.country === country); if (!checkCountry) { alert("현재 존재하지 않는 국가입니다"); return; } const updateMedal = { gold: goldMedal, silver: silverMedal, copper: copperMedal, }; const updateRows = rows.map( (row) => row.country === country ? { ...row, ...updateMedal } // 조건에 맞으면 업데이트된 값 반환 : row // 조건에 맞지 않으면 기존 값 반환 ); setRows(updateRows); }; return ( <div className="contentContainer"> <h1>2024 올림픽 메달 집계</h1> <form className="formContent"> <div className="inputField"> <label>국가명</label> <input type="text" onChange={(e) => setCountry(e.target.value)} ></input> </div> <div className="inputField"> <label>금메달</label> <input type="number" value={goldMedal} onChange={(e) => setGoldMedal(Number(e.target.value))} ></input> </div> <div className="inputField"> <label>은메달</label> <input type="number" value={silverMedal} onChange={(e) => setSilverMedal(Number(e.target.value))} ></input> </div> <div className="inputField"> <label>동메달</label> <input type="number" value={copperMedal} onChange={(e) => setCopperMedal(Number(e.target.value))} ></input> </div> <div className="btnContainer"> <Button variant="contained" type="submit" value={country} onClick={addMedalInfo} > 추가 </Button> <Button variant="contained" onClick={updateMedalInfo}> 업데이트 </Button> </div> </form> <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> <TableHead> <TableRow> <TableCell>국가명</TableCell> <TableCell align="right">금메달</TableCell> <TableCell align="right">은메달</TableCell> <TableCell align="right">동메달</TableCell> <TableCell align="right">액션</TableCell> </TableRow> </TableHead> <TableBody> {rows.map((rows) => ( <TableRow key={rows.id} sx={{ "&:last-child td, &:last-child th": { border: 0 } }} > <TableCell component="th" scope="row"> {rows.country} </TableCell> <TableCell align="right">{rows.gold}</TableCell> <TableCell align="right">{rows.silver}</TableCell> <TableCell align="right">{rows.copper}</TableCell> <TableCell align="right"> <button onClick={() => deleteMedalInfo(rows.id)}>삭제</button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> </div> ); }; export default App;
Material UI를 통해 HTML의 table 태그처럼 꾸몄다. 지금은 다시 HTML만으로 다시 꾸몄다.
위의 코드를 나눌때 UI를 기준으로 모듈을 분리시키려고했다. Props만으로 컴포넌트에서 필요로하는 데이터를 넘겨주기 위해 로직을 구상했는데 끔찍한 결과가 나왔다. 다음은 코드를 기반으로 리팩토링을 했을때의 예시이다.import { useState } from "react"; import "./App.css"; import Button from "@mui/material/Button"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import Paper from "@mui/material/Paper"; import UserForm from "./UserForm"; const App = () => { const [rows, setRows] = useState([ { id: 1, country: "한국", gold: 10, silver: 5, copper: 3, }, ]); const [country, setCountry] = useState(""); const [goldMedal, setGoldMedal] = useState(0); const [silverMedal, setSilverMedal] = useState(0); const [copperMedal, setCopperMedal] = useState(0); const addMedalInfo = () => { const checkCountry = rows.some((row) => row.country === country); if (checkCountry) { alert("이미 존재하는 국가입니다"); return; } const newRow = { id: Date.now(), country, gold: goldMedal, silver: silverMedal, copper: copperMedal, }; setRows([...rows, newRow]); }; const updateMedalInfo = () => { const checkCountry = rows.some((row) => row.country === country); if (!checkCountry) { alert("현재 존재하지 않는 국가입니다"); return; } const updatedRows = rows.map((row) => row.country === country ? { ...row, gold: goldMedal, silver: silverMedal, copper: copperMedal } : row ); setRows(updatedRows); }; const deleteMedalInfo = (id) => { setRows(rows.filter((row) => row.id !== id)); }; return ( <div className="contentContainer"> <h1>2024 올림픽 메달 집계</h1> <UserForm country={country} setCountry={setCountry} goldMedal={goldMedal} setGoldMedal={setGoldMedal} silverMedal={silverMedal} setSilverMedal={setSilverMedal} copperMedal={copperMedal} setCopperMedal={setCopperMedal} addMedalInfo={addMedalInfo} updateMedalInfo={updateMedalInfo} /> <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> <TableHead> <TableRow> <TableCell>국가명</TableCell> <TableCell align="right">금메달</TableCell> <TableCell align="right">은메달</TableCell> <TableCell align="right">동메달</TableCell> <TableCell align="right">액션</TableCell> </TableRow> </TableHead> <TableBody> {rows.map((row) => ( <TableRow key={row.id}> <TableCell>{row.country}</TableCell> <TableCell align="right">{row.gold}</TableCell> <TableCell align="right">{row.silver}</TableCell> <TableCell align="right">{row.copper}</TableCell> <TableCell align="right"> <Button variant="contained" color="error" onClick={() => deleteMedalInfo(row.id)} > 삭제 </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> </div> ); }; export default App;
...이리저리 나눠봐도 코드가 줄어들기는 커녕 가독성이 끔찍해졌다.return ( <div className="contentContainer"> <h1>2024 올림픽 메달 집계</h1> <UserForm country={country} setCountry={setCountry} goldMedal={goldMedal} setGoldMedal={setGoldMedal} silverMedal={silverMedal} setSilverMedal={setSilverMedal} copperMedal={copperMedal} setCopperMedal={setCopperMedal} addMedalInfo={addMedalInfo} updateMedalInfo={updateMedalInfo} />
컴포넌트 1개에 넘겨주는 Props가 이렇게 많아도 되는걸까? 좋은 리액트 코드를 많이 보지는 못했지만 이렇게 작성하는 건 아닌것 같다.'React' 카테고리의 다른 글
Redux, RTK 사용법 정리 - (1) (0) 2025.02.07 React hooks(1) (0) 2025.01.27 투두 리스트 복기 (1) 2025.01.24 리액트 리스트 추가 및 생성 (1) 2025.01.22 TIL - 리액트 개요 (0) 2025.01.20 다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)