글 작성자: 망고좋아
반응형

📖 오늘 배운 내용 - 2022.02.10

  • 그래프 페이지 최적화 작업
  • suspense 공부

📝 최적화 작업 :: React.memo

  • 파이 차트는 달력에 상관없이 모든 기간의 모든 레포의 언어 사용 비율을 보여주는 컴포넌트라서 변경될 필요가 없다.
import React from "react";
import { PieChart, Pie, Sector, Cell } from "recharts";
import githubLangColors from "./github-lang-colors.json";
import * as PieCharts from "./style";

PieChartComponent.defaultProps = {
  codeRatioArray: [
    { name: "JavaScript", value: 44.53 },
    { name: "HTML", value: 35.57 },
    { name: "CSS", value: 13.27 },
    { name: "TypeScript", value: 6.64 },
  ],
};

function PieChartComponent({ codeRatioArray }) {
  const langColor = githubLangColors;
  const COLORS = codeRatioArray.map((it) => {
    const langName = it.name;
    return langColor[langName];
  });

  return (
    <PieCharts.Container>
      <PieCharts.Wrapper>
        <PieCharts.Heading>
          <PieCharts.Title>사용 언어 비율</PieCharts.Title>
          <PieCharts.Description>전체 레포 기준</PieCharts.Description>
        </PieCharts.Heading>
        <PieCharts.RatioWrapper>
          {codeRatioArray &&
            codeRatioArray.map((it, idx) => (
              <PieCharts.LangColorBoxWrapper key={`${it.name}-${it.value}`}>
                <PieCharts.LangColorBox idx={COLORS[idx]} />
                <div>
                  <PieCharts.LangText>{it.value}%</PieCharts.LangText>
                  <PieCharts.LangText>{it.name}</PieCharts.LangText>
                </div>
              </PieCharts.LangColorBoxWrapper>
            ))}
        </PieCharts.RatioWrapper>
      </PieCharts.Wrapper>

      <PieCharts.PieWrapper>
        <PieChart width={200} height={200}>
          <Pie
            data={codeRatioArray}
            cx="50%"
            cy="50%"
            innerRadius={40}
            outerRadius={70}
            fill="#8884d8"
            dataKey="value"
            isAnimationActive={false}
          >
            {codeRatioArray.map((entry, index) => (
              <Cell
                key={`cell-${index}`}
                fill={COLORS[index % COLORS.length]}
              />
            ))}
          </Pie>
        </PieChart>
      </PieCharts.PieWrapper>
    </PieCharts.Container>
  );
}

export default React.memo(PieChartComponent);
  • React.memo를 사용하여 최적화

  • 근데 월간 연간 버튼도 바뀔 필요가 없는데 바뀌고 있다.
import React, { useCallback, useState } from "react";
import { Container } from "@/components/Container/style";
import { DateController } from "@/components/DateController";
import { LineGraph } from "./LineGraph";
import MonthYearBtn from "./MonthYearBtn";
import PieChartComponent from "./PieChart";
import { DateControllerWrapper } from "./style";
export function Graph() {
  const monthButton = true;
  const yearButton = false;
  const toDay = new Date();
  const [date, setDate] = useState(toDay);
  const clickLeft = () => {
    if (date.getFullYear() - 2000 <= 0) return;
    changeDate(-1);
  };
  const clickRight = () => {
    if (toDay.getFullYear() - date.getFullYear() <= 0) return;
    changeDate(1);
  };

  const changeDate = (value) => {
    let newDate = new Date(date.getFullYear() + value, date.getMonth());
    setDate(newDate);
  };

  const goToday = () => {
    setDate(toDay);
  };
  const [clickButtonColor, setClickButtonColor] = useState(true);
  const [checkMonth, setCheckMonth] = useState(false);
  const [graphTitle, setGraphTitle] = useState("월간");

  const handleMonthBtn = () => {
    if (monthButton) {
      setClickButtonColor(monthButton);
      setCheckMonth(false);
      setGraphTitle(checkMonth ? "월간" : "년간");
    }
  };
  const handlYearBtn = () => {
    if (!yearButton) {
      setClickButtonColor(!monthButton);
      setCheckMonth(true);
      setGraphTitle(checkMonth ? "월간" : "년간");
    }
  };

  return (
    <Container>
      <DateControllerWrapper>
        {!checkMonth && (
          <DateController
            date={date}
            clickLeft={clickLeft}
            clickRight={clickRight}
            goToday={goToday}
            month={false}
          />
        )}
      </DateControllerWrapper>

      <MonthYearBtn
        isClick={clickButtonColor}
        handlYearBtn={handlYearBtn}
        handleMonthBtn={handleMonthBtn}
      />
      <LineGraph graphTitle={graphTitle} />
      <PieChartComponent />
    </Container>
  );
}
  • <MonthYearBtn> 컴포넌트에 넘겨주고 있는 handlYearBtn, handleMonthBtn 상태가 변경되어 있어서 리 렌더가 발생하고 있었다. 아래 코드와 같이 useCallback을 이용해서 함수가 재생성되는 부분을 방지해주었다.
const handleMonthBtn = useCallback(() => {
  if (monthButton) {
    setClickButtonColor(monthButton);
    setCheckMonth(false);
    setGraphTitle(checkMonth ? "월간" : "년간");
  }
}, [graphTitle]);
const handlYearBtn = useCallback(() => {
  if (!yearButton) {
    setClickButtonColor(!monthButton);
    setCheckMonth(true);
    setGraphTitle(checkMonth ? "월간" : "년간");
  }
}, [graphTitle]);
  • graphTitle가 변경될 때마다 콜백을 반환하도록 useCallback를 사용했다.

 

📝 Suspense

 

[React] 리액트 React.lazy와 Suspense란?

🎯 리액트 React.lazy와 Suspense란? 📝 React.lazy const SomeComponent = React.lazy(() => import('./SomeComponent')); const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyC..

lakelouise.tistory.com

 

💡 오늘 깨달은 것

  • 라우터가 바뀌면 모든 요소가 렌더링이 일어난다.
  • 재 랜더가 발생할 때마다 콘솔을 찍어본다 -> 내가 의도한 것보다 여러 번 호출되는 경우가 있다. -> 최적화 작업
  • suspense를 사용하면 사용자 경험이 더욱 향상될 거 같다!! 그리고 개발자고 편하고!
반응형