Front-End/React

[React] JSON 파일 데이터 렌더링 (map, sort, filter)

시니철 2024. 10. 3. 22:00

JSON 파일 데이터 렌더링

포켓몬 데이터를 렌더링하고, 정렬과 필터링 기능을 만들기 위해, `pokemon.json` 파일을 불러온 후, `map` 메소드를 활용해 데이터를 렌더링하고, `sort`, `filter` 메소드를 사용하여 정렬과 필터링 기능을 구현할 수 있습니다.

// pokemon.json
[
  {
    "id": 1,
    "name": "이상해씨",
    "types": [
      "풀",
      "독"
    ]
  },
  {
    "id": 2,
    "name": "파이리",
    "types": [
      "불꽃"
    ]
  },
  {
    "id": 3,
    "name": "꼬부기",
    "types": [
      "물"
    ]
  },

 

우선 위의 `pokemon.json` 파일을 추가한 후 `map` 메소드를 활용하여 렌더링합니다.


map으로 렌더링하기

1. JSON 데이터 가져오기

import items from './pokemons';

 

`pokemon.json` 파일의 데이터를 `items`라는 변수로 불러옵니다.

 

2. Pokemon 컴포넌트 정의

function Pokemon({ item }) {
  return (
    <div>
      No.{item.id} {item.name}
    </div>
  );
}

 

`Pokemon` 컴포넌트를 `props`로 전달된 `item`을 받아, 그 포켓몬의 `id`와 `name`을 화면에 표시합니다.

 

3. App 컴포넌트에서 map으로 렌더링

function App() {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <Pokemon item={item} />
        </li>
      ))}
    </ul>
  );
}

 

`App` 컴포넌트는 `items` 배열의 각 요소를 순회하며 `map` 메소드를 사용해 각각의 `item`을 `<Pokemon>` 컴포넌트에 전달합니다.

 

결과적으로 `<ul>` 안에 각 포켓몬이 `<li>` 태그로 감싸진 채로 렌더링됩니다.

// 전체 코드
import items from './pokemons';

function Pokemon({ item }) {
  return (
    <div>
      No.{item.id} {item.name}
    </div>
  );
}

function App() {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <Pokemon item={item} />
        </li>
      ))}
    </ul>
  );
}
 
export default App;

sort로 데이터 정렬하기

포켓몬 데이터 도감 번호 기준으로 오름차순, 내림차순으로 정렬하기 위해, `sort` 메소드를 사용하여 데이터를 쉽게 정렬할 수 있습니다.

 

1. App 컴포넌트 정렬 및 렌더링

function App() {
  const [direction, setDirection] = useState(1);

  const handleAscClick = () => setDirection(1);

  const handleDescClick = () => setDirection(-1);

  const sortedItems = items.sort((a, b) => direction * (a.id - b.id));
  • `useState(1)`을 사용하여 기본 정렬 방향을 오름차순으로 설정합니다.
  • `handleAscClick` 함수는 오름차순으로 정렬할 때 `direction`을 1로 변경합니다.
  • `handleDescClick` 함수는 내림차순으로 정렬할 때 `direction`을 -1로 설정합니다. 
  • `items.sort()`에서 `a.id`와 `b.id`를 비교하고, 그 차이에 `direction` 값을 곱하여 오름차순 또는 내림차순으로 정렬을 제어합니다.

2. 버튼과 리스트 렌더링

  return (
    <div>
      <div>
        <button onClick={handleAscClick}>도감번호 순서대로</button>
        <button onClick={handleDescClick}>도감번호 반대로</button>
      </div>
      <ul>
        {sortedItems.map((item) => (
          <li key={item.id}>
            <Pokemon item={item} />
          </li>
        ))}
      </ul>
    </div>
  );
}

 

`도감번호 순서대로` 버튼을 클릭하면 오름차순 정렬이 적용되고, `도감번호 반대로` 버튼을 클릭하면 내림차순 정렬이 적용됩니다.

정렬된 `sortedItems` 배열을 `map` 메소드를 사용하여 각 포켓몬 데이터를 리스트로 렌더링 합니다.

// 전체 코드
import { useState } from 'react';
import items from './pokemons';

function Pokemon({ item }) {
  return (
    <div>
      No.{item.id} {item.name}
    </div>
  );
}

function App() {
  const [direction, setDirection] = useState(1);

  const handleAscClick = () => setDirection(1);

  const handleDescClick = () => setDirection(-1);

  const sortedItems = items.sort((a, b) => direction * (a.id - b.id));

  return (
    <div>
      <div>
        <button onClick={handleAscClick}>도감번호 순서대로</button>
        <button onClick={handleDescClick}>도감번호 반대로</button>
      </div>
      <ul>
        {sortedItems.map((item) => (
          <li key={item.id}>
            <Pokemon item={item} />
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

filter로 삭제하기

`filter` 메소드를 사용하여 특정 포켓몬을 삭제하는 기능을 만들 수 있습니다.

 

1. Pokemon 컴포넌트와 삭제 핸들러

function Pokemon({ item, onDelete }) {
  const handleDeleteClick = () => onDelete(item.id);

  return (
    <div>
      No.{item.id} {item.name}
      <button onClick={handleDeleteClick}>삭제</button>
    </div>
  );
}

 

`onDelete`는 부모 컴포넌트에서 전달된 삭제 핸들러 함수로, 삭제 버튼이 클릭되면 해당 포켓몬의 `id`를 `onDelete` 함수로 전달합니다.

 

2. App 컴포넌트와 삭제 로직

function App() {
  const [items, setItems] = useState(mockItems);

  const handleDelete = (id) => {
    const nextItems = items.filter((item) => item.id !== id);
    setItems(nextItems);
  };

 

`items` 상태는 초기 값으로 `mockItems`(포켓몬 데이터)를 가지고 있고, `handleDelete` 함수는 삭제하려는 포켓몬의 `id`를 받아, 그 `id`와 다른 항목들만 남긴 새로운 배열을 반환합니다.

이 필터링된 배열을 `setItems`로 상태를 업데이트하여 UI에 반영합니다.

 

3. 리스트 렌더링

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <Pokemon item={item} onDelete={handleDelete} />
        </li>
      ))}
    </ul>
  );
}

 

각 `Pokemon` 컴포넌트에 `onDelete` 핸들러를 전달하여 삭제 버튼 클릭 시 해당 포켓몬을 배열에서 삭제할 수 있도록 합니다.

// 전체 코드
import { useState } from 'react';
import mockItems from './pokemons';

function Pokemon({ item, onDelete }) {
  const handleDeleteClick = () => onDelete(item.id);

  return (
    <div>
      No.{item.id} {item.name}
      <button onClick={handleDeleteClick}>삭제</button>
    </div>
  );
}

function App() {
  const [items, setItems] = useState(mockItems);

  const handleDelete = (id) => {
    const nextItems = items.filter((item) => item.id !== id);
    setItems(nextItems);
  };

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <Pokemon item={item} onDelete={handleDelete} />
        </li>
      ))}
    </ul>
  );
}

export default App;