๐จโ๐ป ํ๋ จ์์ ๊ด์ ์์ ๋ฐ์ | 5๋ถ๋ถ-๐จ ์กฐํ๋ฒ
6042 ๋จ์ด reactcodenewbiecss
style.css
ํ์ผ ํ์ ๋๋ ๊ณ์ ์ ์งํ๋ค.React๋ ๋ค์ํ ๋ฐฉ์์ผ๋ก ๋น์ ์ ๋จ์ผ ์์ฉ ํ๋ก๊ทธ๋จ (SPA) ์ ์ค๊ณํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ทธ๊ฒ์ ๋ถํดํ๊ฒ ์ต๋๋ค.๐๏ธ ์คํ์ผ ๊ฐ์๐๏ธ
React์์ ๊ตฌ์ฑ ์์์ ์คํ์ผ์ ์ค์ ํ๋ ๋ค์ฏ ๊ฐ์ง (ish) ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ผ ์ ์์ต๋๋ค.
์คํ์ผ ์ํธ
์ง๊ธ ์คํ์ผ์ํธ๋ฅผ ์ฌ์ฉํ์ จ์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค.CodePen์์๋ ๋ชจ๋ ํ์ ์คํ์ผ์ํธ๊ฐ ์ ๊ณต๋ฉ๋๋ค.react์์, ์คํ์ผ์ํธ๋ ๋ณดํต ๊ตฌ์ฑ ์์๋ ํ์ด์ง์ ๊ฐ์ ํด๋์ ๋์ฌ ์์ต๋๋ค.์:
Project
|
+-- src
| |
| +-- components
| |
| +-- Nav
| |
| +-- index.jsx
| style.css
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ ์์์nav๋ style.css
๊ฐ์ ธ์ค๊ธฐ import './style.css'
ํ์ผ์ ์ฌ์ฉํฉ๋๋ค.์ด๋ฐ ๋ฐฉ๋ฒ์ ์ํํธ์จ์ด ์์ง๋์ด๊ฐ ๊ณ ์ ์ ์ธ ๋ฐฉ์์ผ๋ก ์คํ์ผ์ํธ๋ฅผ ์ฌ์ฉํ๋๋ก ํ๋ฝํ๋ค.์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.body {
margin: 0;
}
.nav-button {
color: blue;
}
์คํ์ผ์ํธ๋ ๋ธ๋ผ์ฐ์ ์ ์ต์ ํ๋๊ธฐ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ๋ค์ ๋ง๋ค ์ ์์ง๋ง, ์ ์งํ๊ธฐ ์ด๋ ค์ธ ์๋ ์์ต๋๋ค.CSS ๋ชจ๋
CSS ๋ชจ๋์ ๊ฐ์ ์์น์ ์๊ธฐ ๋๋ฌธ์ ์คํ์ผ์ํธ์ ์ ์ฌํฉ๋๋ค(์์ ํ์ผ ๊ตฌ์กฐ ์ฐธ์กฐ).๊ทธ๊ฒ๋ค์ ์๋ก ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๊ฐ์ ธ์ค๊ณ ๋ก์ปฌ์์ ๋ฒ์๋ฅผ ์ ํ๊ธฐ ๋๋ฌธ์ ์คํ์ผ ์ฝ๋๋ฅผ ๋ถ๋ฆฌํ๋ ๋ฐ ๋์ฑ ์ข๋ค.์คํ์ผ์ํธ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ๋ช ๋ช ๋ฉ๋๋ค.์:
module.style.css
.๊ทธ๊ฒ๋ค์ index.jsx
์์ ์๋ก ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์์
ํ๋ค: import styles from './module.style.css'
.์คํ์ผ์ํธ์์ ๋ง๋ styles ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์ก์ธ์คํ ์ ์์ต๋๋ค.๋ค์ ์๋ ๊ทธ๋ค์ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์ค์ ์ ์ผ๋ก ์๊ฐํ๋ค.
import React from 'react';
import styles from './module.style.css';
const Nav = () => (
<nav className={styles.navbar}>
<span className={styles.link}>Home</span>
</nav>
);
export default Nav;
์ฐ๋ฆฌ๊ฐ ๋ชจ๋์์ ๋ง๋ ๋ชจ๋ ์ข
๋ฅ๋ ์ ๊ธฐํธ๋ก ์ ๊ทผํ ์ ์๋ค.๊ทธ๊ฒ๋ค์ ๋งค์ฐ ์ ์ตํ๋ค. ์๋ํ๋ฉด ์คํ์ผ์ ์ญํ ์์ญ (๋ก์ปฌ) ์ ๋ ์ด์ ์คํ์ผ ์ถฉ๋์ด ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. CSS๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋
ธ์ถ๋๊ณ ๋ค์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.๋ฐ๋๋ก ์ ์ญ CSS์ ํผํฉํ๊ธฐ ์ด๋ ค์์lowerCamelCase๋ฅผ ์ฌ์ฉํด์ผ ํ๊ณ ์นํฉ์ด ํ์ํฉ๋๋ค.CSS ํ๋ ์์ํฌ
๋ง์ CSS ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.๋ชจ๋ ๊ฒ์ ๋ฌธ์์ ๋ชจ๋๊ฐ ์๊ณ ์๋ ํน์ฑ์ด ์๋ค.์๋ฅผ ๋ค์ด ๋ชจ๋๊ฐ ์๋ค์ํผ ์๋ด๋ ์ธํฐ๋ท์์ ์น ๊ฐ๋ฐ์์ ์๊ตฌ ์ฌํญ(๊ฒ์ ์๋ด memes)์ด๋ค.๊ทธ๊ฒ๋ค์ ๋งค์ฐ ๋ง๋ค.๋ด๊ฐ ๊ฐ์ฅ ์ข์ํ๋ CSS ํ๋ ์์ํฌ๋ Bulma, Semantic, materialui์ด๋ค.ํจํค์ง ๊ด๋ฆฌ์์ ํจ๊ป ์ค์นํ๊ณ ์ ์ญ์ ์ผ๋ก ๊ฐ์ ธ์ค๊ฑฐ๋ ํ์์ ๋ฐ๋ผ ํ์ผ์ ์ถ๊ฐํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ๊ธฐ ์ฝ์ต๋๋ค.
import React from 'react';
import {
Button,
Container
} from 'react-bulma-components/full';
const Nav = () => (
<Container>
<Button color='danger' size='large' rounded outlined>Home</Button>
</Container>
);
export default Nav;
์์ ์์์๋ CSS ํ๋ ์์ํฌ์์ ์ด์
๋ธ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ ์ค๋๋ค. ์ด๋ฅผ ํ๋์ ์ด์
๋ธ๋ฆฌ๋ก ์ง์ ์ฌ์ฉํ ์ ์์ต๋๋ค.์ด๊ฒ์ ๋ฏธ๋ฆฌ ์ค๊ณ๋์์ง๋ง, ์์์ ์ข
๋ฅ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ํ
๋ง๋ฅผ ์
๋ฐ์ดํธํด์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.์ฐ๋ฆฌ๋ ๋จ์ถ ๊ตฌ์ฑ ์์์ ์ํ, ํฐ, ๋นจ๊ฐ์, ์ค๊ณฝ์ ์ ์ถ๊ฐํ์๋ค.CSS ํ๋ ์์ํฌ๋ ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ ์ฐฝ์คํ ๋ ์ ๊ทผ์ฑ์ ๊ณ ๋ คํ์ฌ ์คํํ๊ธฐ ์ฝ๋ค.๊ทธ๊ฒ๋ค์ ํจ๊ณผ์ ์ผ๋ก ์ต์ ํํ๊ธฐ ์ด๋ ค์ธ ์๋ ์๊ณ , ๋ณด๊ธฐ์ ์ ์ ํ์ง ์์ ์๋ ์๊ณ , ์์ฉ ํ๋ก๊ทธ๋จ์ ํฌ๊ธฐ๋ฅผ ์ฆ๊ฐ์ํฌ ์๋ ์๋ค.
JSS ํ์ฌ
์คํ์ผ๋ง ์ด์ ๋ธ๋ฆฌ์ ์ ์ฌํ๊ฒ JSS๋ JS/JSX ํ์ผ์์ ์์ฑ๋ฉ๋๋ค.๊ทธ๊ฒ๋ค์ ์ฐ๋ฆฌ๊ฐ ์๊ฐํ ๋ค๋ฅธ ๊ฐ๋ ๋ณด๋ค ์ฝ๊ฐ ์ ์ง์ ์ด์ง๋ง ํ ์ ์๋ค.๋ค์ ์์ ์์๋ JSS๊ฐ React์์ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง ๋ณด์ฌ ์ค๋๋ค(์: JSS foundhere์ ํ ํ์ด์ง์ ๊ฐ์ต๋๋ค).
import React from 'react'
import {render} from 'react-dom'
import {createUseStyles} from 'react-jss'
// Create your Styles. Remember, since React-JSS uses the default preset,
// most plugins are available without further configuration needed.
const useStyles = createUseStyles({
myButton: {
color: 'green',
margin: {
// jss-plugin-expand gives more readable syntax
top: 5, // jss-plugin-default-unit makes this 5px
right: 0,
bottom: 0,
left: '1rem'
},
'& span': {
// jss-plugin-nested applies this to a child span
fontWeight: 'bold' // jss-plugin-camel-case turns this into 'font-weight'
}
},
myLabel: {
fontStyle: 'italic'
}
})
// Define the component using these styles and pass it the 'classes' prop.
// Use this to assign scoped class names.
const Button = ({children}) => {
const classes = useStyles()
return (
<button className={classes.myButton}>
<span className={classes.myLabel}>{children}</span>
</button>
)
}
const App = () => <Button>Submit</Button>
render(<App />, document.getElementById('root'))
์ด๋ฐ ๋ฐฉ๋ฒ์ ๊ตฌ์ฑ ์์๋ฅผ ์ค์นํ ๋๋ง ์ฌ์ฉํ ์ ์๋ ๊ฐ๋จํ ํ
๋งํ์ ์ ์ญ ์คํ์ผ์ ํ์ฉํ๋ค.๊ฒ์ผ๋ฅธ ์คํ์ผ์ํธ๋ ํ์ํ ๋๋ง ์กด์ฌํ๋ค.์คํ์ผ์ํธ์ ์ ์ ์์๋ ๋ชจ๋ ์์ ๊ฐ์ ๊ณต์ ๋ฉ๋๋ค.๊ทธ๊ฒ๋ค์ ๊ตญ๋ถ์ ์ธ ๋ฒ์๋ฅผ ์ ๊ณตํ์ง๋ง ํ์ต๊ณผ ์ฝ๊ธฐ๊ฐ ์ด๋ ค์ธ ์๋ ์๋ค.์คํ์ผ ๊ตฌ์ฑ ์์
๋๋ ์ต๊ทผ์ ๋ง ์์ฑํ๋ค. (๊ทธ๋ฌ๋ ์์ฑํ์ง ๋ชปํ๋ค.) ๋๋ ์ด๊ณณ์ ์๋ก์ด ํฌ์ ์กฐํฉ์ ๋ง๋ค์๋ค. shameless plug. ๋๋ ๋๋ถ๋ถ์ ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์คํ์ผํ๋ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ค.์คํ์ผ ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํจํค์ง ๊ด๋ฆฌ์์ ํจ๊ป ์ค์นํ ๋ค์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.๊ทธ๋ฐ ๋ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ฑ ์์๋ฅผ
index.js(x)
ํ์ผ์ ๊ตฌ์ถํฉ๋๋ค.๋ค์์ ๋ด ํฌ์์กฐํฉ์ ํ ์๋ค.import styled from 'styled-components';
export const Container = styled.div`
max-width: 1280px;
margin: 0 auto;
width: 90%;
@media (min-width: 601px) {
width: 90%;
}
@media (min-width: 993px) {
width: 80%;
}
`;
์์ ๊ตฌ์ฑ ์์๋ Container
๋ก ๋ด๋ณด๋ด์ ธ ๊ตฌ์ฑ ์์๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.์ด๊ฒ์ div ํ์์ผ๋ก ๋ํ๋ฉ๋๋ค. ์คํ์ผํ๋ ๊ตฌ์ฑ ์์๋ฅผ ํ
๋งํํ๊ธฐ ์ฌ์ฐ๋ฉฐ ์ค์น ํ SASS์ ์ ๊ทผํ ์ ์์ต๋๋ค.๋๋ npm i styled-components
๋ฅผ ์ฌ์ฉํ ํ์ ์ผ์ ์์ํ๋ค.์ฝ๊ฐ์ ํ์ต ๊ณก์ ๊ณผ ์ฑ๋ฅ์ ๋ถ์ ์ ์ธ ์ํฅ์ ๋ฐ์ ์ ์์ง๋ง, ๊ทธ๋ค์ ์ ๋ง ๋ฉ์ง ์ผ์ ํ๋ค.๋ณด์: ์ง๋ ฌ ์คํ์ผ๋ง
<h1 style={{color: 'blue'}}>Hellow World</h1>
๊ฒฐ๋ก
์ํฐ ํด๋ฆฌ๋ ์คํ์ผ์ ์ ํํ ๋ ๋ง์ ์ ํ์ด ์๋ค.ํ๋ก์ ํธ์ ์ฌ์ฉํ ์ ์๋ ๋ชจ๋ ์คํ์ผ๋ง ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํ๋ค.๋น์ ์ด ์ข์ํ๋ ๊ฒ์ ์ฐพ์์ ์ง์ ์ผ๋ก ๊ทธ๊ฒ์ ์ํ๋ฉด ๋น์ ์ ์คํ์ผ๋ง์ ๊ถ์ธ๊ฐ ๋ ์ ์๋ค.๋ณํจ์์ด ๋ค์ ์ฃผ์ ๋ด์~์๋ก
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐จโ๐ป ํ๋ จ์์ ๊ด์ ์์ ๋ฐ์ | 5๋ถ๋ถ-๐จ ์กฐํ๋ฒ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/guyett92/react-from-a-bootcamper-s-perspective-part-5-styling-methods-45anํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค