내일배움캠프 React_7기 TIL - 18. React 개인과제_Olympic Medal Tracker (1)

·2024년 10월 30일
0

React 입문주차 개인과제 Olympic Medal Tracker(메달 집계 관리 애플리케이션) - 로직구현

  1. 구현 기능
    • 국가, 메달(금, 은, 동) 데이터 집계 테이블
    • 메달 데이터 CRUD (localStorage 활용)

vite 프로젝트 생성 후 작업을 시작했다!

컴포넌트

<Button>, <InputField>, <InputGroup>, <MedalTable> 4개의 컴포넌트를 제작했다.

<Button> : 국가 추가, 수정, 삭제를 실행할 버튼을 컴포넌트화 했다.
<InputField> : 국가, 메달(금, 은, 동) input 또한 컴포넌트화 했다.
<InputGroup> : <InputField>, <Button> 을 자식 컴포넌트로 가진 <form> 컴포넌트이다. Creat, Update 로직 등을 구현했다.

Storage Event

처음엔 가장 자식 컴포넌트인 MedalTable에서 로컬스토리지의 데이터가 변경될 때 컴포넌트의 state를 업데이트하는 로직을 넣는건 어떨까 싶었다.
찾아보니 storage event를 사용할 수 있다고 했다!
MDN 문서 - Window: storage event

useEffect(() => {
	window.addEventListener('storage', fetchData);
	// 컴포넌트 언마운트 시 리스너 제거
  return () => {
    window.removeEventListener('storage', fetchData);
   }, []);
 

하지만... 전혀 작동하지 않았음.

같은 브라우저 탭 내에서는 사용할 수 없다고 한다. 😔
그리고 최하단 컴포넌트에 localStorage의 값을 불러오면 컴포넌트 간 데이터 공유가 어려워질 것 같았다.

다시 고민한 결과, props는 반드시 위에서 아래로 흐른다 (부모 → 자식)는 것을 감안하여 App 컴포넌트에서 useState를 사용하여 로컬스토리지 데이터를 담고 다른 컴포넌트에 setDataList를 props로 전달하기로 했다.

function App() {
  const [dataList, setDataList] = useState([]);
  useEffect(() => {
    const storedData = JSON.parse(localStorage.getItem("medalList")) || [];
    setDataList(storedData);
  }, []);
  return (
    <>
      <div className="container">
        <h2>2024 파리 올림픽</h2>
        <InputGroup setDataList={setDataList} />
        <MedalTable dataList={dataList} setDataList={setDataList} />
      </div>
    </>
  );
}

MedalTable에서도 dataList와 setDataList를 props로 받아 사용하였다. dataList의 변경이 감지되면 tbody UI가 자동으로 업데이트 된다.

function MedalTable({ dataList, setDataList }) {
  const handleDelete = (index) => {
    const updatedDataList = dataList.filter((_, i) => i !== index);
    setDataList(updatedDataList);
    localStorage.setItem("medalList", JSON.stringify(updatedDataList));
  };
  ...
  <tbody>
            {dataList.map((data, i) => (
              <tr key={i}>
                <td>{data.country}</td>
                <td>{data.gold}</td>
                <td>{data.silver}</td>
                <td>{data.bronze}</td>
                <td>
                  <Button text="삭제" onClick={() => handleDelete(i)} />
                </td>
              </tr>
            ))}
          </tbody>

내일은

  • 인풋 값 유효성 체크( 0~99 ), 정렬 기능 추가
  • style 작업
    을 하고 끝마치려고 한다.
profile
내배캠 React_7기 이수중

0개의 댓글

관련 채용 정보