본문 바로가기
CodeIt_Sprint/React로 데이터 다루기

(3)React로 데이터 다루기_3_버튼에 따른 데이터 정렬 기능 추가, 삭제 기능 버튼 추가

by 코잼민 2024. 12. 30.

● 이론1_외부 json 데이터들을 버튼을 누를 시, 삭제 기능 추가해보기

알아야 할 개념들 :

- ★ "App 컴포넌트" 에서 구현한다.

- ★ 논리 순서 : // 암기해야할듯

  •  ①. useState를 이용하여, 정렬 기준에 대한 State 변수 초기화
  •  ②. 정렬 후의 객체 변수를 따로 초기화
  •  ③. 버튼 핸들러 + useState 함수 적용
  •  ④. 버튼 태그 추가 + onClick 속성에 핸들러 적용

Default 코드 :

- App.js 코드

import ReviewList from "./ReviewList";
import items from "../mock.json";

function App() {
  return (
    <div>
      <ReviewList items={items} />
    </div>
  );
}

export default App;

 

 각 순서마다 코드 :

①. useState를 이용하여, 정렬 기준에 대한 State 변수 초기화

import {useState} from 'react'; //useState에 대한 import

function App() {

	const [order , setOrder] = useState('createdAt'); //정렬 기준에 대한 useState 변수 선언
    //, 초기 기준은 생성 기준 날짜값
    
    ..

②. 정렬 후의 객체 변수를 따로 초기화

import {useState} from 'react'; //useState에 대한 import

function App() {

	const [order , setOrder] = useState('createdAt'); //정렬 기준에 대한 useState 변수 선언
    //, 초기 기준은 생성 기준 날짜값
    
    const sortItems = items.sort((a,b)=>{b[order]-a[order]});
    //sort()메소드 + callBack 함수 이용한 가장 높은값에서 낮은값 정렬 반환
    //반환된 값 저장용 sortItems 변수 초기화

③. 버튼 핸들러 + useState 함수 적용

import {useState} from 'react'; //useState에 대한 import

function App() {

	const [order , setOrder] = useState('createdAt'); //정렬 기준에 대한 useState 변수 선언
    //, 초기 기준은 생성 기준 날짜값
    
    const sortItems = items.sort((a,b)=>{b[order]-a[order]});
    //sort()메소드 + callBack 함수 이용한 가장 높은값에서 낮은값 정렬 반환 (내림차순)
    //반환된 값 저장용 sortItems 변수 초기화
    
    const handleLatestSort = ()=>{setOrder("createdAt");};//버튼 핸들러 : 최신순 정렬
    const handleRatingSort = ()=>{setOrder("rating");};//버튼 핸들러 : 평점순 정렬

④. 버튼 태그 추가 + onClick 속성에 핸들러 적용

import {useState} from 'react'; //useState에 대한 import

function App() {

	const [order , setOrder] = useState('createdAt'); //정렬 기준에 대한 useState 변수 선언
    //, 초기 기준은 생성 기준 날짜값
    
    const sortItems = items.sort((a,b)=>{b[order]-a[order]});
    //sort()메소드 + callBack 함수 이용한 가장 높은값에서 낮은값 정렬 반환 (내림차순)
    //반환된 값 저장용 sortItems 변수 초기화
    
    const handleLatestSort = ()=>{setOrder("createdAt");};//버튼 핸들러 : 최신순 정렬
    const handleRatingSort = ()=>{setOrder("rating");};//버튼 핸들러 : 평점순 정렬

	return(
    	<div>
         <button onClick = {handleLatestSort}>최신순</button>
         <button onClick = {handleRatingtSort}>베스트순</button>
     	 <ReviewList items={items} />
   		</div>
    )

}

export default App;

◎ 출력 결과 :

◎ 연습문제 :

실습 설명

이번엔 App 컴포넌트에다 정렬하는 기능을 만들어 봅시다.

아래를 참고해서 App.js 파일을 수정해 주세요.

  • 처음 페이지가 열렸을 때는 최신순으로 보입니다.
  • '최신순' 버튼을 클릭했을 때 생성일(createdAt)이 가까운 순서대로 정렬합니다.
  • '칼로리순' 버튼을 클릭했을 때 칼로리(calorie)가 높은 순서대로 정렬합니다.

 

정답 코드 :

import FoodList from "./FoodList";
import items from "../mock.json";
import { useState } from "react";

function App() {
  const [order, setOrder] = useState("id");

  const sortItems = items.sort((a, b) => {
    return b[order] - a[order];
  });

  const handleCalorieSort = () => {
    setOrder("calorie");
  };
  const handleLatestSort = () => {
    setOrder("createdAt");
  };

  return (
    <div>
      <button onClick={handleLatestSort}>최신순</button>
      <button onClick={handleCalorieSort}>칼로리순</button>
      <FoodList items={items} />
    </div>
  );
}

export default App;

 

● 이론2_외부 json 데이터들을 버튼을 누를 시, 기준에 따라 정렬되는 기능 추가해보기

 알아야 할 개념들 :

- ★ "App 컴포넌트" 에서 구현한다.

- ★ 논리 순서 : // 암기 + 연습 많이 해야 할듯

  •  ①.  json파일에서 불러온 데이터들도 동작에 의해, 구성원이 변경됨 => json의 배열도 useState 선언
  •  ②. 객체 프로퍼티 메소드 filter()를 이용한 삭제 핸들러 작성 : filter + setItems 메소드 
  •  ③. 삭제 버튼은 <ReviewList> 컴포넌트가 아닌 각 Items 내에서 적용되어야 하므로, => <ReviewList>에 프로퍼티로 전달
  •  ④. 전달 받은프로퍼티를 <ReviewItem> 컴포넌트에 프로퍼티로 또 전달
  •  ⑤. 전달 받은 onDelete에서 삭제 버튼 핸들러 작성 // item.id 전달
  •  ⑥. 버튼 태그 추가 , onClick에 핸들러 등록

 

 Default 코드 :

- App.js

import {useState} from 'react'; 

function App() {

	const [order , setOrder] = useState('createdAt'); 
    
    const sortItems = items.sort((a,b)=>{b[order]-a[order]});
    
    const handleLatestSort = ()=>{setOrder("createdAt");};
    const handleRatingSort = ()=>{setOrder("rating");};

	return(
    	<div>
         <button onClick = {handleLatestSort}>최신순</button>
         <button onClick = {handleRatingtSort}>베스트순</button>
     	 <ReviewList items={items} />
   		</div>
    )

}

export default App;

 

 각 순서마다 코드 :

①.  json파일에서 불러온 데이터들도 동작에 의해, 구성원이 변경됨 => json의 배열도 useState 선언

import {useState} from 'react'; 
import mockItems from '../mock.json';//데이터들을 변수로 선언 + import

function App() {
    
    const [items,setItems] = useState(mockItems);
    //동작들 중 데이터 구성원 변경됨 = > useState 선언

}

 

②. 객체 프로퍼티 메소드 filter()를 이용한 삭제 핸들러 작성 : filter + setItems 메소드

import {useState} from 'react'; 
import mockItems from '../mock.json';//데이터들을 변수로 선언 + import

function App() {
    
    const [items,setItems] = useState(mockItems);
    //동작들 중 데이터 구성원 변경됨 = > useState 선언
    
    
    //핸들러 적용
   	const handleDeleteClick = (id) => {
    	//1_ filter를 이용해, 해당 id와 item.id가 일치하는 지 검사
        //2_ filter 후의 반환된 items를 따른 변수로 초기화
        const deleteAfterItems = items.filter((item)=>{id!==item.id});
        
        //3_filter 후의 배열을 setItems에 적용
        setItems(deleteAfterItems);
    };

}

 

③. 삭제 버튼은 <ReviewList> 컴포넌트가 아닌 각 Items 내에서 적용되어야 하므로, => <ReviewList>에 프로퍼티로 전달

import ReviewList from "./ReviewList";


import {useState} from 'react'; 
import mockItems from '../mock.json';//데이터들을 변수로 선언 + import

function App() {
    
    const [items,setItems] = useState(mockItems);
    //동작들 중 데이터 구성원 변경됨 = > useState 선언
    
    
    //핸들러 적용
   	const handleDeleteClick = (id) => {
    	//1_ filter를 이용해, 해당 id와 item.id가 일치하는 지 검사
        //2_ filter 후의 반환된 items를 따른 변수로 초기화
        const deleteAfterItems = items.filter((item)=>{id!==item.id});
        
        //3_filter 후의 배열을 setItems에 적용
        setItems(deleteAfterItems);
    };
    
    return(
    	<div>
        	<ReviewList onDelete={handleDeleteClick}>
            //onDelete 속성을 이용해, 삭제 핸들러를 전달
        </div>
    );

}

 

④. 전달 받은프로퍼티를 <ReviewItem> 컴포넌트에 프로퍼티로 또 전달

⑤. 전달 받은 onDelete에서 삭제 버튼 핸들러 작성 // item.id 전달

⑥. 버튼 태그 추가 , onClick에 핸들러 등록

- ReviewList.js

 

import "./ReviewList.css";


//3_ 전달 받은 onDelete 매개인자 추가
function ReviewItem({ item, onDelete }) {

	//4_ 전달 받은 onDelete 매개인자 추가
  const handleDataDelete = () => onDelete(item.id);

  return (
    <div className="ReviewListItem">
      <img
        className="ReviewListItem-img"
        src={item.imgUrl}
        alt={item.title}
      ></img>
      <div>
        <h1>{item.title}</h1>
        <p>{item.rating}</p>
        <p>{formatDate(item.createdAt)}</p>
        <p>{item.content}</p>
        <button onClick={handleDataDelete}>삭제</button>
      </div>
    </div>
  );
}

//1_ 여기서 onDelete 속성를 매개인자에 추가
function ReviewList({ items, onDelete }) {
  return (
    <ul>
      {items.map((item) => {
        return <ReviewItem item={item} onDelete={onDelete} />;
      })}
      //2_ 전달받은 onDelete 값을 <ReviewItem> 컴포넌트에 다시 전달
    </ul>
  );
}

export default ReviewList;

◎ 연습문제 :

  • 실습 설명

    이번엔 삭제 기능을 만들어 봅시다!이 버튼을 클릭했을 때 items 스테이트의 요소가 삭제되도록 코드를 수정해 주세요.
  • FoodListItem 컴포넌트에 '삭제' 버튼이 추가되어 있는데요.

 

정답 코드 :

- App.js

import FoodList from "./FoodList";
import mockItems from "../mock.json";
import { useState } from "react";

function App() {
  const [order, setOrder] = useState("id");
  const [items, setItems] = useState(mockItems);

  const sortItems = items.sort((a, b) => {
    return b[order] - a[order];
  });

  const handleCalorieSort = () => {
    setOrder("calorie");
  };
  const handleLatestSort = () => {
    setOrder("createdAt");
  };

  const handleDelete = (id) => {
    const deleteAfterData = items.filter((item) => item.id !== id);

    setItems(deleteAfterData);
  };

  return (
    <div>
      <button onClick={handleLatestSort}>최신순</button>
      <button onClick={handleCalorieSort}>칼로리순</button>
      <FoodList items={sortItems} onDelete={handleDelete} />
    </div>
  );
}

export default App;

- FoodList.js

function FoodListItem({ item, onDelete }) {
  const { imgUrl, title, calorie, content } = item;

  const handleDeleteFood = () => onDelete(item.id);

  return (
    <div>
      <img src={imgUrl} alt={title} />
      <div>{title}</div>
      <div>{calorie}</div>
      <div>{content}</div>
      <button onClick={handleDeleteFood}>삭제</button>
    </div>
  );
}

function FoodList({ items, onDelete }) {
  return (
    <ul>
      {items.map((item) => {
        return <FoodListItem item={item} onDelete={onDelete} />;
      })}
    </ul>
  );
}

export default FoodList;