[27] 리액트 동적스타일
동적스타일
어떤 조건에 맞는 스타일속성을 지정해줄때가있다.
이런 동적인스타일을 적용시키는데에는 여러가지 방법이 존재하는데
크게 해당 요소에 인라인속성을줘서 주는방법이있고
미리 클래스에 스타일을 적용시킨다음에 해당조건에맞으면 클래스이름을 주거나 삭제시키는 방법으로 할수도있다.
import React, { useState } from "react";
import Button from "../../UI/Button/Button";
import "./CourseInput.css";
const CourseInput = (props) => {
const [enteredValue, setEnteredValue] = useState("");
const [isValid, setIsValid] = useState(true);
const goalInputChangeHandler = (event) => {
if (event.target.value.trim().length > 0) {
setIsValid(true);
}
setEnteredValue(event.target.value);
};
const formSubmitHandler = (event) => {
event.preventDefault();
if (enteredValue.trim().length === 0) {
setIsValid(false);
return;
}
props.onAddGoal(enteredValue);
};
return (
<form onSubmit={formSubmitHandler}>
<div className={`form-control`}>
**<label style={{ boderColor: !isValid ? "red" : "black" }}>**
Course Goal
</label>
<input type="text" onChange={goalInputChangeHandler} />
</div>
<Button type="submit">Add Goal</Button>
</form>
);
};
export default CourseInput;
isValid 라는 state 값을 통해서 인라인 속성을 제어하고있다.
첫번째방법의 문제점은 인라인속성으로 주기때문에 다른스타일을 무시하고 적용될수있다는점이다.
두번째방법을 사용할때 리액트로 해당 상태를 관리하는 state 를 생성한뒤
state 를 통해서 클래스 이름을 동적으로 할당하여 관리를 할수있다.
코드를 확인해보자
import React, { useState } from "react";
import Button from "../../UI/Button/Button";
import "./CourseInput.css";
const CourseInput = (props) => {
const [enteredValue, setEnteredValue] = useState("");
const [isValid, setIsValid] = useState(true);
const goalInputChangeHandler = (event) => {
if (event.target.value.trim().length > 0) {
setIsValid(true);
}
setEnteredValue(event.target.value);
};
const formSubmitHandler = (event) => {
event.preventDefault();
if (enteredValue.trim().length === 0) {
setIsValid(false);
return;
}
props.onAddGoal(enteredValue);
};
return (
<form onSubmit={formSubmitHandler}>
**<div className={`form-control ${!isValid ? "invalid" : ""}`}>**
<label>Course Goal</label>
<input type="text" onChange={goalInputChangeHandler} />
</div>
<Button type="submit">Add Goal</Button>
</form>
);
};
export default CourseInput;
isValid 라는 state 를 통해서 invalid 라는 클래스 이름을 추가하고있다.
해당 클래스에는 미리 css 스타일링을 적용한상태이다.
그런데 이런스타일들의 단점은 import 를 해당 파일에만 했다고해서 모듈화되 적용시킨 js 파일에서만 동작하는것이 아닌 , 모든 파일에 영향을 줄수있다.
그렇기때문에 프로젝트가 커지면 커질수록 , 다른사람이 같은 클래스네임을 작성했다면 해당 클래스 네임에도
스타일이 적용될수있다는 얘기다 .
이런 것들을 제어하기위해서 styled components 패키지 를 사용해보자 .
공식 페이지 에 들어가서 패키지 설치하는방법을 보고 따라해보자
https://styled-components.com/
npm 을 통해서 설치했다면 프로젝트내에서 사용할수있다.
먼저 import 를 해준뒤 사용해보자
import styled from 'styled-components';
import styled from "styled-components";
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);
}
`;
export default Button;
이런식으로 styled 의 메소드로 button 태그를 사용하여 아래에 스타일을 적용시켜 컴포넌트화 시켜 사용할수있다.
크롬브라우저의 개발자도구를 통해 styled-components 를 통해 생성한 태그를 보면 class 이름이 중복되지않게 적용된것을볼수있다.
이를통해서 다른곳에서 사용하더라도 클래스이름이 유니크하기때문에 중복적으로 사용할 일이 없어지게되고 ,
위 두가지 방법의 문제점을 해결할수있게된다.
CSS module
기존에 동적스타일을 지정 할때 클래스이름이 다른 어디선가 동일하게 사용된다면
해당 클래스에도 스타일이 적용되어 예기치않는 일들이 있어 문제가 된다 했다.
이는 styled-components 패키지에서 클래스이름을 유니크한값으로
지정해주는 것으로 그런 문제들을 해결했다.
하지만 한파일내에 스타일코드와 컴포넌트를 구성하는 코드들이 있기때문에
코드 가독성이 좋지않다고 생각하게되어 다른 방법을 배워보았다.
먼저 CSS module 은 파일이름을 [이름].module.css. 로 저장해야된다.
**import styles from "./CourseInput.module.css";**
그리고 해당하는 파일을 임의의 이름으로 임포트를 한뒤 해당 변수로 사용하면된다.
import React, { useState } from "react";
import Button from "../../UI/Button/Button";
import styles from "./CourseInput.module.css";
const CourseInput = (props) => {
const [enteredValue, setEnteredValue] = useState("");
const [isValid, setIsValid] = useState(true);
const goalInputChangeHandler = (event) => {
if (event.target.value.trim().length > 0) {
setIsValid(true);
console.log(isValid);
}
setEnteredValue(event.target.value);
};
const formSubmitHandler = (event) => {
event.preventDefault();
if (enteredValue.trim().length === 0) {
setIsValid(false);
return;
}
props.onAddGoal(enteredValue);
};
return (
<form onSubmit={formSubmitHandler}>
<div
**className={`${styles["form-control"]} ${!isValid && styles.invalid}`}
>**
<label style={{ boderColor: !isValid ? "red" : "black" }}>
Course Goal
</label>
<input type="text" onChange={goalInputChangeHandler} />
</div>
<Button type="submit">Add Goal</Button>
</form>
);
};
export default CourseInput;
기본적으로 styles를통해서 css 의 클래스들을 접근해서 사용할수있고 그릴이용해 조건을 걸어 동적스타일링을 할수도있다.
이렇게 className 을 지정하면 개발자도구에서 확인했을때 styled-components 와 동일하게 유니크한값을 임의로 지정하기때문에 문제를 해결하면서도 css 와 js 를 분리하여 코드가독성을 높일수있다.