[DAY - 70] vanilla.js 예제 React.js 변환

2023. 6. 13. 22:12·🔥 부트캠프-웹 개발 🔥/React

https://github.com/yeonhub/module-assignment

 

GitHub - yeonhub/module-assignment: javascript module

javascript module. Contribute to yeonhub/module-assignment development by creating an account on GitHub.

github.com

지난번에 vanilla javascript와 module을 사용해서 명단 리스트를 구현해보았다.

이에 몇가지 기능을 추가 해 React로 만들어 보았다.

 

  • 명단 추가
  • 명단 초기화
  • 명단 개별 삭제

 

import React, { useRef, useState } from 'react';
import '../assets/css/reset.css'
import './Staff.scss'
import dataList from '../assets/api/StaffData'
import StaffList from './StaffList';
import StaffForm from './StaffForm';

const Staff = () => {
    const [data, setData] = useState(dataList)
    const no = useRef(dataList.length + 1)
    const [isAdd, setIsAdd] = useState(false)
    const showAdd = () => {
        setIsAdd(!isAdd)
    }
    const onDel = (id) => {
        setData(data.filter(item => item.id !== id))
    }
    const onDelAll = () => {
        setData([]);
    }
    const onRe = () => {
        setData(dataList);
    }
    const onAdd = (user) =>{
        setData(
            [
                ...data,
                {id : no.current++,...user}
            ]
        )
    }
    const onLike =(id)=>{   
        setData(data.map(item => item.id === id ? { ...item, like: !item.like } : item))
    }

    return (
        <div className='wrap'>
            <div className="list">
                <h2>직원 명단</h2>
                <p>
                    <button onClick={onDelAll}>전체 삭제</button>
                    <button onClick={onRe}>초기화</button>
                </p>
                <button className='add' onClick={showAdd}>명단 추가</button>
                {
                    isAdd && <StaffForm onAdd={onAdd}/>
                }
                <StaffList data={data} onDel={onDel} onLike={onLike}/>
            </div>
        </div>
    );
};

export default Staff;

 

1) 명단 추가

import React, { useRef, useState } from 'react';

const StaffForm = ({ onAdd }) => {
    const [user, setUser] = useState(
        { name: '', job: '', tel: '', img: '' }
    )
    const nameRef = useRef(null)
    const { name, job, tel, img } = user
    const changeInput = e => {
        const { name, value } = e.target
        setUser({ ...user, [name]: value })
    }
    const onSubmit = e => {
        e.preventDefault();
        if (!name || !job || !tel || !img) return
        onAdd(user)
        setUser({ name: '', job: '', tel: '', img: '' })
        nameRef.current.focus();
    }
    return (
        <form onSubmit={onSubmit}>
            <p>
                <label htmlFor="">이름</label>
                <input type="text" name='name' value={name} onChange={changeInput} ref={nameRef} placeholder='이름'/>
            </p>
            <p>
                <label htmlFor="">직업</label>
                <input type="text" name='job' value={job} onChange={changeInput} placeholder='직업'/>
            </p>
            <p>
                <label htmlFor="">연락처</label>
                <input type="text" name='tel' value={tel} onChange={changeInput} placeholder='010-0000-0000'/>
            </p>
            <p>
                <label htmlFor="">사진</label>
                <input type="text" name='img' value={img} onChange={changeInput} placeholder='사진 링크'/>
            </p>
            <p>
                <button>추가</button>
            </p>
        </form>
    );
};

export default StaffForm;

 

명단 추가는 form 태그와 input 태그를 사용해 구현했다.

onSubmit을 추가해 엔터를 눌렀을 때도 추가되도록 했다.

각각 항목에 맞는 name과 value를 가져와서 user에 담아준다. 그 뒤 onAdd함수에 user를 넣어주면 Staff.js에서 받아 처리가 가능하다.

 

    const onAdd = (user) =>{
        setData(
            [
                ...data,
                {id : no.current++,...user}
            ]
        )
    }

 

 

2) 명단 초기화

    const onDelAll = () => {
        setData([]);
    }

 

명단 초기화는 간단하게 data에 빈 배열을 넣어 만들었다.

 

 

3) 명단 개별 삭제

import React from 'react';

const StaffItem = ({ item, onDel, onLike }) => {
    const { id, img, name, job, tel, like } = item
    return (
        <li>
            <img src={img} alt={name} />
            <div>
                <strong>{name}</strong>
                <span>{job}</span>
                <p>{tel}</p>
            </div>
            <div>
                {
                    like ? <i className='xi-heart' onClick={() => onLike(id)}></i> : <i className='xi-heart-o' onClick={() => onLike(id)}></i>
                }
                <button onClick={() => onDel(id)}>퇴사</button>
            </div>
        </li>
    );
};

export default StaffItem;

 

data 배열을 받아 li로 뿌려주는 컴포넌트에서 삭제 button을 만들 때 onDel함수를 붙여주었다.

부모 컴포넌트에서 id값도 받아왔기 때문에 클릭한 해당 id를 가져올 수 있었다.

 

    const onDel = (id) => {
        setData(data.filter(item => item.id !== id))
    }

 

그 후 최상위 컴포넌트에서 filter를 이용해 해당 id와 같지 않은 객체들을 data에 새로 넣어주어 개별 삭제가 가능하도록 했다.

 

'🔥 부트캠프-웹 개발 🔥/React' 카테고리의 다른 글
  • [DAY - 72] checkbox, useEffect
  • [DAY - 71] 탭 메뉴(class, 상태변수)
  • [DAY - 69] 추가 삭제 수정, useRef
  • [DAY - 68] popup, 컴포넌트 값 전달, 함수/useState 줄이기
Yeonhub
Yeonhub
✨ https://github.com/yeonhub 📧 lsy3237@gmail.com
  • Yeonhub
    비 전공자의 Be developer
    Yeonhub
  • 전체
    오늘
    어제
    • 전체보기 (169)
      • 🔍 Tech 🔍 (19)
        • Front-End (11)
        • Back-End (4)
        • AI (1)
        • Server (1)
        • Etc (2)
      • 💡 원티드 프리온보딩 챌린지 💡 (14)
        • PRE-ONBOARDING_AI (11월) (1)
        • PRE-ONBOARDING_FE (2월) (2)
        • PRE-ONBOARDING_FE (1월) (2)
        • PRE-ONBOARDING_FE (12월) (9)
      • 🔥 부트캠프-웹 개발 🔥 (118)
        • HTML5 (7)
        • CSS3 (21)
        • JavaScript (27)
        • JavaScript_advanced (9)
        • React (24)
        • Next (1)
        • MYSql (5)
        • Node (5)
        • 오늘하날(개인프로젝트) (12)
        • 이젠제주투어(팀프로젝트) (7)
      • 💻 CS 💻 (1)
        • 알고리즘 (1)
      • ⚡ 코딩테스트 ⚡ (11)
        • JavaScript (11)
      • 📚 Books 📚 (6)
        • 클린 아키텍처 (2)
        • 인사이드 자바스크립트 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    react native bottom sheet
    expo admob
    react native expo fcm
    expo deep linking
    python node
    expo google map
    rn bottom sheet
    react vite
    react native firebase analytics
    expo 길찾기
    expo fcm
    node crontab
    php node
    react native analytics
    expo node fcm
    javascript fcm
    node cron
    node fcm
    컴파운드 컴포넌트 패턴
    expo map
    프론트엔드 테스트코드
    bottom sheet
    rn admob
    라스콘4
    expo fcm push
    node.js fcm
    react native admob
    라스콘
    expo 지도
    Node
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Yeonhub
[DAY - 70] vanilla.js 예제 React.js 변환
상단으로

티스토리툴바