Act99 기술블로그

[Nextjs] 주식사이트 만들기-9 코인 정보 슬라이드 (Carousel) 만들기 본문

개발팁저장소/nextjs

[Nextjs] 주식사이트 만들기-9 코인 정보 슬라이드 (Carousel) 만들기

Act99 2021. 12. 17. 15:59

이번에는 코인 정보 슬라이드를 만들어주었다.

시간초의 경우 setInterval & useEffect & useRef 로 만들지 않고

useInterval hook 을 이용해서 만들었다.

 

결과물은 아래와 같다.

 

 

내용을 딱히 넣을 것이 없어서 Description 데이터를 800자만 불러왔다.

데이터가 html tag 까지 갖고 있어, dangerouslySetInnerHTML 을 이용했다.

 

코드는 다음과 같다.

 

- homeSlider.tsx

 

import { useEffect, useState } from "react";
import CoinSliderCard from "../../components/slider/coinSliderCard";
import useInterval from "../../hooks/useInterval";
import { FiArrowLeft, FiArrowRight } from "react-icons/fi";

type Props = {
  data: any;
};

const HomeSlider: React.FC<Props> = ({ data }) => {
  const [currentSlide, setCurrentSlide] = useState(0);
  const [paused, setPaused] = useState(false);

  const changeDescData = () => {
    const dataArray: any[] = [];
    for (let i = 0; i < data?.length; i++) {
      dataArray.push(data[i]);
    }
    dataArray.sort(
      (a: any, b: any) => parseFloat(a.change) - parseFloat(b.change)
    );
    return dataArray;
  };

  console.log(changeDescData().length);

  useInterval(() => {
    if (paused === false) {
      currentSlide === changeDescData().length - 1
        ? setCurrentSlide(0)
        : setCurrentSlide(currentSlide + 1);
    }
  }, 5000);

  console.log(currentSlide);

  const nextSlide = () => {
    if (currentSlide === changeDescData().length - 1) {
      setCurrentSlide(0);
    } else setCurrentSlide(currentSlide + 1);
  };
  const prevSlide = () => {
    if (currentSlide === 0) {
      setCurrentSlide(changeDescData().length - 1);
    } else setCurrentSlide(currentSlide - 1);
  };

  const volumeDescData = () => {
    const dataArray: any[] = [];
    for (let i = 0; i < data?.length; i++) {
      dataArray.push(data[i]);
    }
    dataArray.sort(
      (a: any, b: any) => parseFloat(a.volume) - parseFloat(b.volume)
    );
    return dataArray;
  };
  console.log(changeDescData()[currentSlide]);
  //   console.log(changeDescData()[0]);
  return (
    <div className=" w-10/12">
      <h3 className=" font-bold text-2xl pl-5 pr-16 py-5">
        Today Cryptos Transcation Price
      </h3>
      <div
        className="flex flex-row w-10/12 items-center"
        onMouseLeave={() => {
          setPaused(false);
        }}
        onMouseEnter={() => {
          setPaused(true);
        }}
      >
        <button onClick={prevSlide}>
          <FiArrowLeft color="#f7a600" size={"24"} />
        </button>
        <CoinSliderCard data={changeDescData()[currentSlide]} />
        <button onClick={nextSlide}>
          {" "}
          <FiArrowRight color="#f7a600" size={"24"} />
        </button>
      </div>
    </div>
  );
};

export default HomeSlider;

 

 

 

 

- coinSliderCards.tsx

import MilBilCal from "../../functions/milBilCal";

type Props = {
  data: any;
};

const CoinSliderCard: React.FC<Props> = ({ data }) => {
  return (
    <div className=" bg-white  rounded-lg my-5 mx-10 min-w-full">
      <div className=" flex flex-row items-center justify-between px-3 pt-3">
        <div className=" flex flex-row items-center">
          <img src={data.iconUrl} className=" w-8 h-8" />
          <h3 className=" font-bold">{data.symbol}</h3>
        </div>
        <div
          className={
            data.change > 0
              ? " bg-green-400 rounded-md px-1"
              : "bg-red-400 rounded-md px-1"
          }
        >
          <h3 className=" font-bold text-white text-sm">{data.change + "%"}</h3>
        </div>
      </div>

      <div className=" p-3 flex flex-col">
        <h3 className=" font-bold text-lg">
          {parseFloat(data.price) < 100
            ? parseFloat(data.price).toLocaleString(undefined, {
                maximumFractionDigits: 4,
              }) +
              " " +
              "$"
            : parseFloat(data.price).toLocaleString(undefined, {
                maximumFractionDigits: 2,
              }) +
              " " +
              "$"}
        </h3>
        <h3 className=" text-sm text-gray-500 py-2">
          {"24H Turnover" + " " + MilBilCal(data.volume) + "[USD]"}
        </h3>
      </div>
      <div className=" h-80">
        <hr className=" bg-black" />
        <h3 className=" font-bold text-lg pl-5 pr-16 py-5">Description</h3>
        <div className="flex flex-row">
          <h3
            className=" font-bold text-sm pl-5 pr-16 py-5"
            dangerouslySetInnerHTML={{
              __html: data.description.substr(0, 800),
            }}
          ></h3>
        </div>
      </div>
    </div>
  );
};

export default CoinSliderCard;

 

useState를 이용하여 슬라이드의 순서를 정해주었으며, 마우스가 슬라이더 위에 올라왔을 때,

정지해있도록 만들어놓았다. (onMouseEnter / onMouseLeave => setPaused)

 

결과물.

 

 

https://github.com/act99/stock-chat

 

GitHub - act99/stock-chat: stock&coin chart with Chatting Nestjs, Apollo, Redux, Redux-Toolkit

stock&coin chart with Chatting Nestjs, Apollo, Redux, Redux-Toolkit - GitHub - act99/stock-chat: stock&coin chart with Chatting Nestjs, Apollo, Redux, Redux-Toolkit

github.com

 

다음 할 일은

 

현재 BTC 차트만 구현시켜놓았으니

state 값에 변화를 주어 다른 코인 데이터를 불러와

다른 코인 차트를 구현시키는..... 음

 

쉽게말해서 버튼 누를때마다 코인 차트가 변하는 것을 구현할 생각이다.

 

Redux 를 이용해 상태관리를 할 예정이다.