์ด ๊ธ์ udemy์ React ์๋ฒฝ ๊ฐ์ด๋ with Redux, Next.js, TypeScript ๊ฐ์ข๋ฅผ ๋ฐํ์ผ๋ก ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
82. ๋ชจ๋ ์๊ฐ
- Conditional & Dynamic Styles
- Styled Components
- CSS Modules
error
error:03000086:digital envelope routines::initialization error
- ์์ค์ฝ๋๋ฅผ ๋ค์ด๋ฐ์ ์คํํ์ ๋ค์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ๋ ธ๋ 17๊ด๋ จ ์๋ฌ๋ก nvm ์ ์ฌ์ฉํ์ฌ node ๋ฒ์ ์ ๋ฎ์ถฐ ๋ค์ ์คํํ๋ ์ ์ ์๋๋์๋ค.
83. ๋์ ์ธ๋ผ์ธ ์คํ์ผ ์ค์ ํ๊ธฐ
- input ์ฐฝ์ ์ ๋ ฅ ์์ด Add Goal์ ๋๋ ์ ๋ color๋ฅผ ๋์ ์ผ๋ก ๋ฐ๊ฟ์ฃผ๋๋ก ํ๋ค.
<div className="form-control">
<label style={{ color: !isValid ? "red" : "black" }}>Course Goal</label>
<input
style={{
borderColor: !isValid ? "red" : "black",
background: !isValid ? "salmon" : "transparent",
}}
type="text"
onChange={goalInputChangeHandler}
/>
</div>
- ํ์ง๋ง inline ์คํ์ผ์ css์ ์ต์ฐ์ ์์๋ฅผ ๋๊ธฐ ๋๋ฌธ์ ๋ชจ๋ style์ ์ค๋ฒ๋ผ์ด๋ ํ๋ค. ๊ทธ๋์ ํด๋น ๋ฐฉ๋ฒ์ ์ ํธํ์ง ์๋๋ค. (๊ทธ๋์ ์ ๋๋ก style ์๋จน์ผ๋ฉด..๋ฌด์กฐ๊ฑด inline styling ์ ์ฉํ์๋๋ฐ, ์ผ๊ฐํด์ผ ๋๊ฒ ๋ค....๐ )
84. ๋์ ์ผ๋ก CSS ํด๋์ค ์ค์ ํ๊ธฐ
- backticks (๋ฐฑํฑ) ์ฌ์ฉํ๊ธฐ, ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ผ๋ก ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด์ด๋ผ๊ณ ๋ ๋ถ๋ฆฐ๋ค.
- ์ ๊ฐ๋จํ ๊ตฌ๋ฌธ์ผ๋ก ๋์ ์ธ ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ ์ ์๋ค.
.form-control.invalid input {
border-color: red;
background: rgb(255, 202, 202)
}
.form-control.invlid label {
color: red;
}
<form onSubmit={formSubmitHandler}>
<div className={`form-control ${!isValid ? "invalid" : ""}`}>
<label style={{ color: !isValid ? "red" : "black" }}>Course Goal</label>
<input type="text" onChange={goalInputChangeHandler} />
</div>
<Button type="submit">Add Goal</Button>
</form>
85. Styled Components ์๊ฐ
- ํน์ ์คํ์ผ์ด ์ฒจ๋ถ๋ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ถํ ์ ์๋๋ก ๋์์ฃผ๋ ํจํค์ง์ด๋ค.
- https://styled-components.com/
- Actually, styled package has methods for all HTML elements. It has p method for a paragraph h1, h2, and so on for the h1, h2 tags, div to create a div and so on.
const Button = props => {
return (
<button type={props.type} className="button" onClick={props.onClick}>
{props.children}
</button>
);
};
export default Button;
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;
→ button tag์ ์ ์ฉ๋ ์ด์ํ class 2๊ฐ๋ฅผ ๋ณผ ์ ์๋ค. ์ด๋ ์ฐ๋ฆฌ๊ฐ ์ค์ ํ ๊ฒ์ด ์๋๋ผ styled-components ํจํค์ง์ ์ํด ๋์ ์ผ๋ก ์์ฑ๋ ํด๋์ค ์ด๋ฆ์ด๋ค. ์ด ํจํค์ง๋ ๊ฒฐ๊ตญ ์ฐ๋ฆฌ๊ฐ ์ค์ ํ style์ ๋ณด๊ณ ์์ฑ๋ ํด๋์ค ์ด๋ฆ์ผ๋ก ์ด ์คํ์ผ์ ๊ฐ์ธ๋๋ฐ ๋ชจ๋ ํด๋์ค๋ ๊ณ ์ ํ ์ด๋ฆ์ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ฑ์ ์๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์ํฅ์ ์ฃผ์ง ์๋๋ค. ๊ทธ๋์ ์ด class๋ฅผ ์ ์ญ css๋ก ์ถ๊ฐํ ๊ฒ์ด๋ค.
→ ํ์ง๋ง ๋ชจ๋ styled components๋ง๋ค ๊ณ ์ ํ class name์ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ์ค์ ํ style์ app ๋ด์ ๋ค๋ฅธ component์๋ ์ ๋ ์ํฅ์ ์ฃผ์ง ์๋๋ค. unique class name ์ styled componet ๋ณ๋ก ๊ณ ์ ํ๊ธฐ ๋๋ฌธ ๐ ์ด๊ฒ ๋ฐ๋ก styled-component ๊ฐ ๋์ํ๋ ๋ฐฉ์์ด๋ค.
86. Styled Components & ๋์ Props
border: 1px solid ${(props) => (props.invalid ? "red" : "#ccc")};
background: ${(props) => (props.invalid ? "red" : "#ccc")}
→ ; ํ๋ ์ฐจ์ด๋ก ์ ์ฉ์ด ๋์๋ค๊ฐ ์๋์๋ค๊ฐ ํ๋ค...?!
87. Styled Components & ๋ฏธ๋์ด ์ฟผ๋ฆฌ
- ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ฅผ ํจ๊ป ์ฌ์ฉํ ์๋ ์๋ค.
const Button = styled.button`
width: 100%;
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;
@media (min-width: 768px) {
width: auto;
}
&:focus {
outline: none;
}
&:hover,
&:active {
background: #ac0e77;
border-color: #ac0e77;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
}
`;
export default Button;
88. CSS ๋ชจ๋ ์ฌ์ฉํ๊ธฐ
- https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
- st yled ์ปดํฌ๋ํธ๋ฅผ ์ข์ํ๊ฑด, ๊ทธ๋ ์ง ์๊ฑด ๊ทธ๊ฒ์ ์์ ํ ๊ฐ์ธ์ ์ธ ์ทจํฅ์ด๋ค. ๊ฐ์ธ์ ์ผ๋ก ํ์๋ css๋ css ํ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํ๋ค. (css ํ์ผ๊ณผ js ๋ถ๋ฆฌ)
- css ๋ชจ๋์ ์ด ๊ธฐ๋ฅ์ ์ง์ํ๋๋ก ์ค์ ๋ ํ๋ก์ ํธ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. why? ๋ธ๋ผ์ฐ์ ์์ ์ฝ๋๊ฐ ์คํ๋๊ธฐ ์ ์ ์ฝ๋์ ๋ณํ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋คํํ ๋ฆฌ์กํธ์ฑ์ผ๋ก ์์ฑํ project๋ ๊ธฐ๋ณธ์ ์ผ๋ก css module์ ์ง์ํ๋๋ก ์ค์ ๋์ด ์๋ค.
- *.module.css : ๊ธฐ๋ณธ์ ์ผ๋ก css ๋ชจ๋์ด ์๋ํ๋๋ก ์ฝ๋๋ฅผ ๋ณํํ๋ผ๊ณ ์ปดํ์ผ ํ๋ก์ธ์ค์๊ฒ ๋ณด๋ด๋ ์ ํธ์ด๋ค.
import styles from "./Button.module.css";
const Button = (props) => {
return (
<button type={props.type} className={styles.button} onClick={props.onClick}>
{props.children}
</button>
);
};
export default Button;
→ ์ปดํฌ๋ํฐ์ด๋ฆ_ํด๋์ค ์ด๋ฆ_๊ณ ์ ํ ํด์๊ฐ ์ผ๋ก ๊ตฌ์ฑ๋์ด์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. css module ๋ด๋ถ ํ๋ก์ธ์ค๋ css ํด๋์ค๋ css ํ์ผ์ ํตํด ๊ทธ ํด๋์ค์ ์ด๋ฆ์ ๊ณ ์ ํ๊ฒ ๋ฐ๊พผ๋ค. ์ด๊ฒ ๋ฐ๋ก ํต์ฌ ์์ !
→ importํ๋ ๋ชจ๋ css ํ์ผ์ ๊ณ ์ ํ๊ฒ ๋ง๋ ๋ค.
→ ๋ ๋๋ง๋ DOM์์ <head> ๋ถ๋ถ์ ํ์ฅํด ๋ณด๋ฉด ์๋ก ๋ง๋ค์ด์ง ํด๋์ค๋ฅผ ๋ณผ ์ ์๋ค.
→ css module์ cssํ์ผ์์ ์ค์ ํ css style์ ๋ฒ์๊ฐ ์ด file์ import ํ๋ ์ปดํฌ๋ํธ์ ํ์ ๋๋ค๋ ๊ฒ์ ํ์คํ๊ฒ ํด์ค๋ค.
→ ๊ฐ๋ฐ์์ธ ์ฐ๋ฆฌ๊ฐ ๋ฏธ๋ฆฌ ์ ์๋ ์์ง๋ง ๋์ ์ผ๋ก ๋ง๋ค์ด์ง ํด๋์ค name๊ณผ ์ปดํฌ๋ํธ๋ฅผ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ!
89. CSS ๋ชจ๋์ ์ฌ์ฉํ ๋์ ์คํ์ผ
<div className={styles["form-control"]}></div>
<div className={`${styles["form-control"]} ${!isValid && styles.invalid}`}></div>
์ ๋ฆฌ
1. css ๋ง ์ฌ์ฉํ๊ธฐ
2. styled ์ปดํฌ๋ํธ ์ฌ์ฉ
3. css module ์ฌ์ฉ
๊ฐ์ ์ ํธํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
90. ๋ชจ๋ ๋ฆฌ์์ค
- ๊ฐ์ ์ฐธ๊ณ