Recent Posts
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
관리 메뉴

개발자 박가나

[241030 TIL] 본캠프 21일차 ('Medal Tracker 만들기' 프로젝트 2일차) 본문

내일배움캠프

[241030 TIL] 본캠프 21일차 ('Medal Tracker 만들기' 프로젝트 2일차)

gnchoco97 2024. 10. 30. 16:22

  📌 오늘의 TIL

  • [Medal Tracker 만들기] 프로젝트

 

 

 [Madal Tracker] 프로젝트 

기능 구현 - 메달 집계 내역 조회

  • useState()로 메달 집계 내역을 저장할 변수 list를 생성한다.
  • list에 저장된 데이터를 map()을 이용해서 화면에 보여준다.
/* App.jsx */

const [list, setList] = useState([]);

<List data={list.length}>
    {list.map((item, index) => {
    	return <ListItem key={index} data={item} />;
    })}
</List>

 

기능 구현 - 메달 집계 내역 추가

  • 버튼 클릭 시 onSubmit()을 실행한다.
  • 클릭된 버튼이 '국가 추가' 버튼인 경우, handleCreate()를 실행한다.
  • 입력된 값을 바탕으로 객체를 생성한 뒤, list에 추가해준다.
  • 화면을 새로고침 해도 데이터를 유지할 수 있도록 처리 결과를 localStorage에도 저장해준다.
/* App.jsx */

/* form submit 이벤트 */
const handleSubmit = (e) => {
    e.preventDefault();
    e.nativeEvent.submitter.name === 'create' && handleCreate();
};

/* 추가 이벤트 */
const handleCreate = () => {
    // 국가명을 입력하지 않은 경우
    if (!country) {
    	window.alert('국가명을 입력해주세요.');
    }
    // 입력한 국가가 이미 등록되어 있는 경우
    else if (list.filter((item) => item.country === country).length) {
    	window.alert('해당 국가가 이미 등록되어 있습니다.');
    }
    // 메달 값으로 0보다 작은 값을 입력한 경우
    else if (parseInt(gold) < 0 || parseInt(silver) < 0 || parseInt(bronze) < 0) {
    	window.alert('메달의 갯수는 0보다 작을 수 없습니다.');
    }
    // 메달 값으로 100보다 큰 값을 입력한 경우
    else if (parseInt(gold) > 100 || parseInt(silver) > 100 || parseInt(bronze) > 100) {
    	window.alert('메달의 갯수는 100보다 클 수 없습니다.');
    } else {
        // 추가할 데이터
        const value = {
            country,
            gold: parseInt(gold) || 0,
            silver: parseInt(silver) || 0,
            bronze: parseInt(bronze) || 0,
            total: (parseInt(gold) || 0) + (parseInt(silver) || 0) + (parseInt(bronze) || 0)
        };

        // 추가한 결과가 반영된 list
        const result = [...list, value].sort((a, b) => b[sort] - a[sort]);

        window.localStorage.setItem('medalTracker', JSON.stringify(result));
        setList(result);
        setCountry('');
        setGold(0);
        setSilver(0);
        setBronze(0);
    }
};

<Form handleSubmit={handleSubmit}>
    <FormInput type="text" placeholder="국가 입력" name="국가명" value={country} handleChange={changeCountry} />
    <FormInput type="number" name="금메달" value={gold} handleChange={changeGold} />
    <FormInput type="number" name="은메달" value={silver} handleChange={changeSilver} />
    <FormInput type="number" name="동메달" value={bronze} handleChange={changeBronze} />
    <Button type="create" name="국가 추가" />
</Form>

 

기능 구현 - 메달 집계 내역 수정

  • 버튼 클릭 시 onSubmit()을 실행한다.
  • 클릭된 버튼이 '업데이트' 버튼인 경우, handleUpdate()를 실행한다.
  • 입력된 값을 바탕으로 객체를 특정한 뒤, 해당 객체를 list에서 찾아서 수정해준다.
  • 화면을 새로고침 해도 데이터를 유지할 수 있도록  처리 결과를 localStorage에도 저장해준다.
/* App.jsx */

/* form submit 이벤트 */
const handleSubmit = (e) => {
    e.preventDefault();
    e.nativeEvent.submitter.name === 'update' && handleUpdate();
};

/* 수정 이벤트 */
const handleUpdate = () => {
    let updated = list.filter((item) => item.country === country)[0];

    // 입력한 국가가 등록되어있지 않은 경우
    if (!updated) {
    	window.alert('해당 국가가 등록되어 있지 않습니다.');
    } else {
        // 수정할 데이터
        const value = {
            country,
            gold: parseInt(gold) || 0,
            silver: parseInt(silver) || 0,
            bronze: parseInt(bronze) || 0,
            total: (parseInt(gold) || 0) + (parseInt(silver) || 0) + (parseInt(bronze) || 0)
        };

        // 수정한 결과가 반영된 list
        const result = [...list.filter((item) => item.country !== country), value].sort((a, b) => b[sort] - a[sort]);

        window.localStorage.setItem('medalTracker', JSON.stringify(result));
        setList(result);
        setCountry('');
        setGold(0);
        setSilver(0);
        setBronze(0);
    }
};

<Form handleSubmit={handleSubmit}>
    <FormInput type="text" placeholder="국가 입력" name="국가명" value={country} handleChange={changeCountry} />
    <FormInput type="number" name="금메달" value={gold} handleChange={changeGold} />
    <FormInput type="number" name="은메달" value={silver} handleChange={changeSilver} />
    <FormInput type="number" name="동메달" value={bronze} handleChange={changeBronze} />
    <Button type="update" name="업데이트" />
</Form>

 

기능 구현 - 메달 집계 내역 삭제

  • 버튼 클릭 시 handleDelete()를 실행한다.
  • 전달받은 값을 바탕으로 객체를 특정한 뒤, 해당 객체를 list에서 찾아서 삭제해준다.
  • 화면을 새로고침 해도 데이터를 유지할 수 있도록 처리 결과를 localStorage에도 저장해준다.
/* App.jsx */

/* 삭제 이벤트 */
const handleDelete = (deleted) => {
    if (confirm(`${deleted}의 메달 집계 내역을 삭제하시겠습니까?`)) {
        // 삭제한 결과가 반영된 list
        const result = [...list.filter((item) => item.country !== deleted)].sort((a, b) => b[sort] - a[sort]);

        window.localStorage.setItem('medalTracker', JSON.stringify(result));
        setList(result);
    }
};

<List data={list.length}>
    {list.map((item, index) => {
    	return <ListItem key={index} data={item} handleDelete={() => handleDelete(item.country)} />;
    })}
</List>
/* ListItem.jsx */

<ValueContainer>
    <Value>{data.country}</Value>
    <Value>{data.gold}</Value>
    <Value>{data.silver}</Value>
    <Value>{data.bronze}</Value>
    <Value>{data.total}</Value>
    <Value>
    	<Button type="delete" handleDelete={handleDelete} />
    </Value>
</ValueContainer>

 

기능 구현 - 정렬

  • useState()로 정렬 기준을 저장할 변수 sort를 생성한다.
  • 전달받은 값을 바탕으로 list 데이터를 정렬해준다.
/* App.jsx */

const [sort, setSort] = useState('gold');

/* 정렬 기준 변경 이벤트 */
const handleSort = (value) => {
    setSort(value);
    list.sort((a, b) => b[value] - a[value]);
};

<List data={list.length} sort={sort} handleSort={handleSort}>
    {list.map((item, index) => {
    	return <ListItem key={index} data={item} />;
    })}
</List>
/* List.jsx */

<TitleContainer>
    <Title>국가명</Title>
    <Title onClick={() => handleSort('gold')}>
        금메달
        <Sort>{sort === 'gold' ? '▼' : '▽'} </Sort>
    </Title>
    <Title onClick={() => handleSort('silver')}>
        은메달
        <Sort>{sort === 'silver' ? '▼' : '▽'} </Sort>
    </Title>
    <Title onClick={() => handleSort('bronze')}>
        동메달
        <Sort>{sort === 'bronze' ? '▼' : '▽'} </Sort>
    </Title>
    <Title onClick={() => handleSort('total')}>
        합계
        <Sort>{sort === 'total' ? '▼' : '▽'} </Sort>
    </Title>
    <Title></Title>
</TitleContainer>