📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[React] 동일 컴포넌트를 각각 다르게 스타일링(CSS)하는 방법

문제

const MyButton = () => {
    return (
        <button className="MyButton"></button>
    )
}

export default MyButton;

MyButton이라는 하나의 컴포넌트가 있다. 이 컴포넌트의 용도는 사이트 여기저기에서 버튼 역할을 수행하고자 한다.

버튼도 버튼마다 역할이 있고, 기능이 다르기 때문에 컴포넌트도 이에 따라 여러 개 만들어야 한다고 생각할 것이다.

하지만, 리액트에는 Props라는 혜자 기능이 있기 때문에 1개의 컴포넌트로 씹고 뜯고 맛보며 제대로 뽕을 뽑을 수 있다.

또한 CSS 스타일링 역시 각각 버튼의 기능마다 다르게 줄 수 있다. 바로 Props를 이용해서 말이다.

 

해결

import {MyButton} from "./Components/MyButton";

const Home = () => {
    return (
        <div>
            <MyButton type={"add"} text={"추가"} />
            <MyButton type={"remove"} text={"삭제"} />
            <MyButton type={"default"} text={"확인"} />
        </div>
    )
}

export default Home;

먼저 MyButton 컴포넌트를 사용하는 Home 컴포넌트의 코드이다.

총 3개의 버튼을 사용했고, 각각 기능은 다르다고 가정하겠다. 버튼 모두 동일한 컴포넌트를 쓰기 때문에 type이라는 Props로 각 버튼의 기능을 구별해주었고, text라는 Props를 통해 버튼의 내용을 입력시켜 주었다.

 

const MyButton = ({type, text}) => {
    return (
        <button className=["MyButton", `MyButton_${type}`].join(" ")>{text}</button>
    )
}

MyButton.defaultProps = {
    type: "default"
}

export default MyButton;

MyButton 컴포넌트에서는 Home 컴포넌트로부터 전달받은 Props들을 각 위치에 할당해준다.

text의 경우 버튼의 내용이므로 간단히 버튼 태그 안에 할당해주었다. type 같은 경우가 중요한데, 우리는 1개의 컴포넌트가 type마다 다른 CSS 스타일링을 하고자 했다.

 

먼저, 우리가 일반적으로 HTML 태그에 복수의 클래스 이름을 설정할 땐 <div class="title title_a"> 이런 식의 띄어쓰기로 구분했다는 걸 기억해야 한다. 우리가 할 것은 버튼에 공통 클래스인 "MyButton"과 타입마다 다른 "MyButton_타입", 총 2가지 클래스 이름을 button 태그에 설정해줄 것이다.

 

리액트에서 복수의 className을 설정할 땐 join() 함수가 사용된다. 그러기 위해 먼저 클래스들을 하나의 배열로 묶어준다. 한 가지 주의할 점은 전달받은 Props를 클래스로 사용할 땐 ₩(백 틱)을 이용해 문자화 시켜 사용해야 한다. 그다음 join(" ") 함수를 이용하여 띄어쓰기로 구분해주면 우리가 원했던 복수의 클래스를 설정해줄 수 있다.

 

Props로 type이 전달되지 않을 경우를 대비하여 defaultProps를 이용해 type의 default 값을 "default"로 설정하는 것도 잊지 말자!

 

import {MyButton} from "./Components/MyButton";

const Home = () => {
    return (
        <div>
            <MyButton type={"add"} text={"추가"} />
            <MyButton type={"remove"} text={"삭제"} />
            <MyButton type={"default"} text={"확인"} />
            <MyButton type={"menu"} text={"목록"} /> // CSS에 menu 타입 스타일은 없다고 가정.
        </div>
    )
}

export default Home;

Props를 이용해 하나의 컴포넌트를 여기저기 사용할 땐 주의해야할 점들이 많이 있다.

만약, type에 따른 CSS 스타일링을 add, remove, default만 했다고 했을 때 이 3가지 외의 타입이 들어오면 해당 컴포넌트는 어떻게 대처해야 할까?

 

const MyButton = ({type, text}) => {
    const btnType = ["add", "remove"].includes(type) ? type : default;

    return (
        <button className=["MyButton", `MyButton_${btnType}`].join(" ")>{text}</button>
    )
}

MyButton.defaultProps = {
    type: "default"
}

export default MyButton;

includes() 함수를 이용해 간단한 장치를 마련하면 된다. includes() 함수는 배열에 해당 값이 있는지 없는지 확인해서 있으면 true, 없으면 false를 반환하는 함수이다. type이 add나 remove이면 그대로 반환하고, 아니면 default를 반환하게 해서 add, remove, default 외에 다른 type이 들어오는 것을 방지해주었다.

 

1. Props를 이용하면 1개의 컴포넌트를 씹고 뜯고 맛보고 즐기는 등 여러 가지로 사용할 수 있다.
2. <button className=["myButton", `myButton_${type}`].join(" ")>복수 클래스 입력.
3. 미리 정한 Props외에 다른 값이 들어오는 게 싫다면 includes() 함수와 삼항 연산자를 이용하자.