styled Components 패키지는 사용하면 특정 스타일이 첨부된 컴포넌트를 구축할 수 있도록 도와주는 패키지입니다.
특정 스타일이 첨부되는 컴포넌트에서만 영향을 미치고 다른 컴포넌트에는 전혀 영향을 미치지 않습니다.
우선 styled Components 접속하시거나 위의 명령어를 터미널에 입력하여 패키지를 다운로드합니다.
styled-components
Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress 💅🏾
styled-components.com
기존 스타일링
import React from 'react';
import './Button.css';
const Button = props => {
return (
<button type={props.type} className="button" onClick={props.onClick}>
{props.children}
</button>
);
};
export default Button;
기존에는 Button 컴포넌트를 생성하여 CSS를 import 해 사용해주었습니다.
styled Components 패키지를 사용하여 기존의 스타일링을 변경해겠습니다.
사용방법
import styled from "styled-components";
우선 styled Components에서 styled를 import 해줍니다.
const Button = styled.button``;
다음으로 기존 방식처럼 상수 Button을 생성해주지만 해당 상수는 더 이상 함수형 컴포넌트를 저장하지 않기 때문에
위의 코드 예시처럼 작성해줍니다.
styled는 styled Components에서 import 한 객체이고 button은 styled 객체의 메서드입니다.
styled 객체가 호출할 수 있는 메서드는 html에 있는 모든 요소에 대한 메서드입니다.
저의 경우 button 컴포넌트를 생성하는 것이 목표이기 때문에 button 메서드를 호출해주었습니다.
styled Components 패키지에서는 button()으로 메서드를 호출하는 대신 뒤에 백 틱( `` )을 붙여 호출합니다.
이렇게 사용한 button 메서드는 새로운 Button 컴포넌트를 반환하게 됩니다.
const Button = styled.button`
.button {
font: inherit;
padding: 0.5rem 1.5rem;
border: 1px solid #8b005d;
color: white;
background: #8b005d;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
cursor: pointer;
}
.button:focus {
outline: none;
}
.button:hover,
.button:active {
background: #ac0e77;
border-color: #ac0e77;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
}
`;
위의 코드처럼 백 틱 사이에는 여러 줄의 문자열을 작성할 수 있습니다.
기존의 import 했던 CSS의 코드를 백 틱 사이에 넣어주었습니다.
여기서 문제는 button 메서드는 Button 컴포넌트를 반환만 하지 클래스를 따로 지정을 해주지 않기 때문에
백 틱 사이의 CSS 코드가 적용이 안된다는 것입니다.
대신 백 틱 사이에 전달한 CSS 코드를 button 메서드에 직접적으로 영향을 주게 할 수 있습니다.
const Button = styled.button`
font: inherit;
padding: 0.5rem 1.5rem;
border: 1px solid #8b005d;
color: white;
background: #8b005d;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
cursor: pointer;
&:focus {
outline: none;
}
&:hover,
&:active {
background: #ac0e77;
border-color: #ac0e77;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
}
`;
위의 코드처럼 선택자를 제거하면 백 틱 사이의 CSS 코드는 메서드가 호출되어 반환하는 Button 컴포넌트에 추가되며
상수 Button까지 영향을 받게 됩니다.
가상 선택자의 경우는 styled Components 패키지에서 지원하는 & 기호와 사용합니다.
& 기호는 생성한 컴포넌트에 대해 가상 선택자를 사용하겠다고 패키지에 선언하는 것을 의미합니다.
즉 "버튼에 focus가 있으면 스타일을 적용해줘"를 의미하게 되는 것입니다.
만약 .button label처럼 button 클래스 안에 있는 label 태그에 접근을 하고 싶은 경우에도 & 기호를 사용해주시면 됩니다.
( & label )
이렇게 생성된 Button 컴포넌트에는 기존에 전달하는 props가 적용되게 됩니다.
기존의 button에는 onClick 속성을 추가해서 type을 설정할 수 있는데
생성된 Button 컴포넌트는 styled Components에 의해 button 메서드가 내부적으로 사용하고 있습니다.
기존 코드
return (
<form onSubmit={formSubmitHandler}>
<div className={`form-control ${!isValid ? "invalid" : ""}`}>
{/* isValid가 false이면 글자색 red, true이면 글자색 black */}
<label>Course Goal</label>
<input type="text" onChange={goalInputChangeHandler} />
</div>
<Button type="submit">Add Goal</Button>
</form>
);
변경 코드
const FormControl = styled.div`
margin: 0.5rem 0;
&.invalid label {
color: red;
}
&.invalid input {
border-color: red;
background-color: salmon;
}
& label {
font-weight: bold;
display: block;
margin-bottom: 0.5rem;
}
& input {
display: block;
width: 100%;
border: 1px solid #ccc;
font: inherit;
line-height: 1.5rem;
padding: 0 0.25rem;
}
& input:focus {
outline: none;
background: #fad0ec;
border-color: #8b005d;
}
`;
return (
<form onSubmit={formSubmitHandler}>
// styled-component 적용--------------------------------------------
<FormControl className={className={!isValid ? "invalid" : ""}}>
//-----------------------------------------------------------------
{/* isValid가 false이면 글자색 red, true이면 글자색 black */}
<label>Course Goal</label>
<input type="text" onChange={goalInputChangeHandler} />
</FormControl>
<Button type="submit">Add Goal</Button>
</form>
);
};
기존 코드에서 className에 전달했던 form-control은 제거해주어도 적용이 되게 됩니다.
기존 코드에서 className에 삼항 연산자로 전달했던
${!isValid ? "invalid" : ""} 는 템플릿 리터럴, 즉 백 틱 없이 전달이 가능해집니다.
동적으로 스타일링하는 또 다른 방법을 아래 코드 예시와 함께 정리해보겠습니다.
return (
<form onSubmit={formSubmitHandler}>
<FormControl invalid={!isValid}>
<label>Course Goal</label>
<input type="text" onChange={goalInputChangeHandler} />
</FormControl>
<Button type="submit">Add Goal</Button>
</form>
);
styled Components 패키지를 사용해 생성한 컴포넌트에 props를 전달해주었습니다.
const FormControl = styled.div`
margin: 0.5rem 0;
& label {
font-weight: bold;
display: block;
margin-bottom: 0.5rem;
color: ${(props) => [props.invalid ? "red" : "black"]};
}
& input {
display: block;
width: 100%;
border: 1px solid ${(props) => (props.invalid ? "red" : "#ccc")};
background: ${(props) => (props.invalid ? "red" : "transparent")};
font: inherit;
line-height: 1.5rem;
padding: 0 0.25rem;
}
& input:focus {
outline: none;
background: #fad0ec;
border-color: #8b005d;
}
`;
${} 사이에는 함수를 받을 수 있고 해당 함수는 전달받은 props를 인자로 받습니다.
전달받은 props, invalid가 false이면 "red"가 적용되고, true이면 기존의 컬러가 적용되게 동적으로 스타일링을 해주었습니다.
이렇게 props에 기반하여 스타일 일부를 동적으로 변경하는 것이 가능합니다.
'React' 카테고리의 다른 글
불 필요한 <div> 제거하기 (Fragment) (0) | 2022.10.03 |
---|---|
CSS 모듈을 사용한 스타일 적용 (0) | 2022.10.02 |
동적으로 클래스 설정하기(State와 삼항연산자) (0) | 2022.10.01 |
동적으로 인라인 스타일 설정하기(State와 삼항연산자) (0) | 2022.10.01 |
여러개의 State 하나로 합치기 (2) | 2022.09.25 |