동적스타일
어떤 조건에 맞는 스타일속성을 지정해줄때가있다.
이런 동적인스타일을 적용시키는데에는 여러가지 방법이 존재하는데
크게 해당 요소에 인라인속성을줘서 주는방법이있고
미리 클래스에 스타일을 적용시킨다음에 해당조건에맞으면 클래스이름을 주거나 삭제시키는 방법으로 할수도있다.
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 를 분리하여 코드가독성을 높일수있다.
'프론트엔드 > React' 카테고리의 다른 글
[29] 리액트 useEffect (0) | 2022.12.09 |
---|---|
[28]리액트 ref 와 state (1) | 2022.12.09 |
[26] 리액트 상태 끌어올리기 (1) | 2022.12.06 |
[25] react 의 JSX (0) | 2022.12.05 |
[13일차] 리액트 HOC (0) | 2022.11.16 |