[React] 버튼 클릭시 데이터 정렬, 각각 렌더링 하기

glow_soon·2022년 2월 27일
0

React

목록 보기
33/52

무작위로 저장된 데이터를 알파벳 순으로 정렬해 렌더링해주는 버튼을 만들어 보았따

[
    {"id": 0,"name": "Kwon"},
    {"id": 1,"name": "Yoon"},
    {"id": 2,"name": "Kim"},
    {"id":3, "name":"ASH ISLAND", "kor_name":"애쉬 아일랜드","img":"https://user-images.githubusercontent.com/86250281/155518228-979a54ed-8ece-4ed1-9ea5-f121b5f0a49e.png"},
    {"id":4, "name":"BLOO", "kor_name":"블루", "img":"https://user-images.githubusercontent.com/86250281/155535571-24040887-e0c4-40c7-8138-29b323c4533d.png"},
    {"id":5, "name":"BEENZINO", "kor_name":"빈지노", "img":"https://user-images.githubusercontent.com/86250281/155535749-4a3b10c0-4b1a-4a4d-bc97-5096d2962a87.png"},
    {"id":6, "name":"JUNG SANG SOO", "kor_name":"정상수", "img":"https://user-images.githubusercontent.com/86250281/155874075-e9120da7-e123-4234-8574-23661f134149.jpg"}
]

이런 데이터가 내 mock 서버에 저장되어있는 상태이다

let [alphabet, setAlphabet] = useState("");

let alphaBtn = Array.from({ length: 26 }, (v, i) =>
    String.fromCharCode(i + 65)
  );

버튼을 만들기위한 alpahBtn 변수와 유저가 클릭시 각각의 버튼의 value를 저장할 alpahbet state를 선언했다.

      {loading ? (
        <div className="spinner">
          <Spinner animation="border" variant="primary" />
          <p>Loading...</p>
        </div> //loading UI용
      ) : (
        alphaBtn.map((item) => {
          return (
            <button
              onClick={(e) => {
                setAlphabet(e.target.value);
              }}
              value={item}
            >
              {item}
            </button>
          );
        })
      )}

alphaBtn 변수에는 A,B,C,D,E.....값이 저장되어 있으므로 map 함수를 통해 하나씩 돌며 렌더링 하게 해주었고, 해당 버튼값을 value에 저장, onClick시 state변경함수로 해당 value값을 가지게 했다

<div className="container">
        <div className="main-box">
          {mydata.map((x) => { // mydata : 데이터 저장 되어있는 state
            if (
              x.name.substring(0, 1).toLowerCase() === alphabet.toLowerCase()
            ) {
              return (
                <div className="artist">
                  <img src={x.img} alt={x.name} />
                  <p>
                    {x.name} {"(" + x.kor_name + ")"}
                  </p>
                </div>
              );
            }
          })}
        </div>
      </div>

데이터가 저장되어있는 mydata state에 map함수를 돌렸다

x.name.substring(0, 1).toLowerCase() -> mydata안에 name에 저장된 값을 substring 함수로 맨 앞글자만 뽑아낸 후 소문자로 변환

alphabet.toLowerCase() -> 현재 유저가 누른 버튼 value가 alphabet state에 저장되어있다, 소문자로 변환
비교 연산을 통해 같다면 해당 데이터를 렌더링 하게 해주었다

누를때마다 데이터를 검색하기 때문에 데이터가 겁나 많다면 효율성 측면에서는 안 좋을거 같기도 하다, 간단한 토이프로젝트 (단어장 만들기 등) 에 써먹으면 좋을거 같다

전체 코드

import "./App.css";
import "./Main.scss";
import { useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";
import axios from "axios";

function App() {
  let [mydata, setData] = useState([]); // 데이터 저장용
  let [alphabet, setAlphabet] = useState(""); // 알파벳 클릭시 value 저장용
  let [loading, setLoading] = useState(true); // loading UI용

  let alphaBtn = Array.from({ length: 26 }, (v, i) =>
    String.fromCharCode(i + 65)
  );
  useEffect(() => {
    axios
      .get("서버 url")
      .then((result) => {
        setData(result.data);
        setLoading(false);
      })
      .catch(() => {});
  }, []);

  return (
    <div className="App">
      {loading ? (
        <div className="spinner">
          <Spinner animation="border" variant="primary" />
          <p>Loading...</p>
        </div>
      ) : (
        alphaBtn.map((item) => {
          return (
            <button
              onClick={(e) => {
                setAlphabet(e.target.value);
              }}
              value={item}
            >
              {item}
            </button>
          );
        })
      )}

      {alphabet == "" ? <h1>초기 화면</h1> : null}
      
      <div className="container">
        <div className="main-box">
          {mydata.map((x) => {
            if (
              x.name.substring(0, 1).toLowerCase() === alphabet.toLowerCase()
            ) {
              return (
                <div className="artist">
                  <img src={x.img} alt={x.name} />
                  <p>
                    {x.name} {"(" + x.kor_name + ")"}
                  </p>
                </div>
              );
            }
          })}
        </div>
      </div>
    </div>
  );
 }
export default App;
profile
나는야 코린이

0개의 댓글