NextJS + Typescript에서 SVG 아이콘 사용하고 색상 변경하기

루비·2023년 6월 1일
0

NextJS

목록 보기
4/7

원인

이번 프로젝트에서 remix icon을 사용하게 되었는데, remix-react 버전이 없는 줄 알고서 진행해였다. 그래도 나중이라는건 잘 모르니 기록으로 남겨둔다.

개발환경

Nextjs + typescript + sass

설치

npm i @svgr/webpack
yarn add @svgr/webpack

next.config.js

/** @type {import('next').NextConfig} */
const path = require("path");
const nextConfig = {
  reactStrictMode: true,
  sassOptions: {
    includePaths: [path.join(__dirname, "styles")],
  },
  webpack: (config) => {
    config.module.rules.push({
      test: /\.svg$/,
      use: ["@svgr/webpack"],
    });
    return config;
  },
};

module.exports = nextConfig;

icons 폴더 만들기

svg 파일 설정

// fill = "current" 필수다. 이건 색상을 현재로 고정한다는것.
<svg xmlns="http://www.w3.org/2000/svg" width="current"
  height="current" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"></path><path d="M21 19.9997C21 20.552 20.5523 20.9997 20 20.9997H4C3.44772 20.9997 3 20.552 3 19.9997V9.48882C3 9.18023 3.14247 8.88893 3.38606 8.69947L11.3861 2.47725C11.7472 2.19639 12.2528 2.19639 12.6139 2.47725L20.6139 8.69947C20.8575 8.88893 21 9.18023 21 9.48882V19.9997ZM19 18.9997V9.97791L12 4.53346L5 9.97791V18.9997H19Z" fill="current"></path></svg>

사용할 아이콘 적용하기

import React from "react";
import styles from "@/styles/layout/_dashboardSidebar.module.scss";
import { useRouter } from "next/router";
import Link from "next/link";
import AlertFillIcon from "remixicon-react/AlertFillIcon";
import HomeIcon from "@/assets/icons/dashboard/home.svg";
const DashboardSidebar = () => {
  const router = useRouter();
  const link = router.pathname;

  const menu = [
    {
      menu: "대시보드",
      href: "/dashboard",
      icon: <HomeIcon />,
    },
  ];
  const activeColor = "#4263eb";
  const inactiveColor = "#868e96";

  return (
    <div className={styles.container}>
      <div className={styles.logo}>DOTPAY</div>
      <div className={styles.buttonContainer}>
        <button onClick={() => router.push("/remittance")}>
          송금하기
          <AlertFillIcon />
        </button>
      </div>

      <ul>
        {
          menu.map((menu) => {
            const isActive = link === menu.href;
            const iconColor = isActive ? activeColor : inactiveColor;

            return (
              <li
                className={isActive ? `${styles.selected}` : `${styles.none}`}
                key={menu.menu}>
                <div className={styles.icon}>
                  {React.cloneElement(menu.icon, { fill: iconColor })}
                </div>
                <Link href={menu.href}>{menu.menu}</Link>
              </li>
            );
          })
        }
      </ul>
    </div>
  );
};

export default DashboardSidebar;


React.cloneElement 무엇인가?

결론 : 잘 사용하지 말아라. 별로 오래되었고 좋진 않음. 근데 암튼 문제를 해결해야하니까 사용했던 것이다. 알아도 나쁠 건 없어서 사용하는 것이다.

cloneElement()는 React에서 사용되는 메서드로, 기존 React 엘리먼트를 복제하여 새로운 프로퍼티와/또는 자식 요소를 추가 또는 수정할 때 사용됩니다. 이 메서드는 기존 엘리먼트를 복제하고 원하는 변경 사항을 적용한 새로운 엘리먼트를 반환합니다.

cloneElement() 메서드의 구문은 다음과 같습니다:

React.cloneElement(element, props, children)
  • element: 복제할 React 엘리먼트입니다.
  • props (선택사항): 추가하거나 수정할 새로운 프로퍼티입니다.
  • children (선택사항): 새로운 자식 요소입니다. 기존의 자식 요소를 대체하거나 추가할 수 있습니다.

cloneElement()를 사용하여 React 엘리먼트를 복제하면, 복제된 엘리먼트에 새로운 프로퍼티와/또는 자식 요소를 적용할 수 있습니다. 이는 React 컴포넌트에서 동적으로 엘리먼트를 조작하고 조건부로 변경사항을 적용하는 데 유용합니다.

예를 들어, 다음은 cloneElement()를 사용하여 기존 엘리먼트의 스타일을 변경하고 새로운 클래스를 추가하는 예시입니다:

const originalElement = <div className="original">Hello, World!</div>;

const clonedElement = React.cloneElement(originalElement, {
  style: { color: "red" },
  className: "modified",
});

// clonedElement는 다음과 같이 변경됩니다:
// <div className="modified" style={{ color: "red" }}>Hello, World!</div>

위의 예시에서 cloneElement() 메서드는 originalElement를 복제하고, 스타일을 변경하고 클래스를 추가한 새로운 clonedElement를 반환합니다.

cloneElement()를 사용하면 기존 엘리먼트의 구조를 유지하면서 필요한 변경사항을 적용할 수 있으므로, 동적인 UI 조작이나 조건부 렌더링 등에서 유용하게 사용될 수 있습니다.

{React.cloneElement(menu.icon, { fill: iconColor })}
// 그래서 fill 부분을 설정해여 조작한다. 

출처 : React 공식 홈페이지 - cloneElement()
https://react.dev/reference/react/cloneElement

profile
개발훠훠

0개의 댓글