SASS
Sass(๋๋ Syntactically Awesome Stylesheets)๋ CSS์ ํ์ฅ๋ ๋ฌธ๋ฒ์ ์ ๊ณตํ๋ ์คํ์ผ ์ํธ ์ธ์ด์ ๋๋ค. Sass๋ ๋ ๊ฐ๊ฒฐํ๊ณ ์ ์ง๋ณด์๊ฐ ์ฌ์ด CSS ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋๋ก ๋์์ฃผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ฃผ๋ก CSS์ ๊ธฐ๋ฅ์ ํ์ฅํ๊ณ ์ค๋ณต์ ์ค์ด๋ฉฐ ๊ฐ๋ ์ฑ์ ํฅ์์ํค๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
โ๏ธSASS๋ก ์์ฑํ๋ฉด CSS๋ก ๋ฐ๊ฟ์ฃผ๋ ์์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, CRA๊ฐ ํด์ค๋ค๊ณ ํ๋ค.
npm install -D sass
#layout-header {
background-color: yellowgreen;
height: 80px;
padding: 0 3rem;
display: flex;
align-items: center;
.layout-header-logo {
> a {
font-size: 24px;
font-weight: 700;
color: black;
text-decoration: none;
}
}
nav {
a {
font-size: 15px;
font-weight: 500;
}
}
}
sass๋ฅผ ์ฌ์ฉํ๋ฉด ํ์์์๋ฅผ css์ฝ๋๋ธ๋ก ๋ด์์ ์์ฑํ ์ ์๋ค.
๐๐ป ์ ํ์๋ฅผ ํธํ๊ฒ ์์ฑํ ์ ์๊ฒ๋๋ค.
a {
font-size: 15px;
font-weight: 500;
&:hover {
color: blue;
}
}
โจ &๋ฅผ ์ฌ์ฉํด ์๊ธฐ ์์ ์ ์ง์นญํ ์ ์๋ค.
Movie.module.scss
tailwind-css
npm install -D tailwindcss
npx tailwindcss init
https://tailwindcss.com/docs/guides/create-react-app
Install Tailwind CSS with Create React App - Tailwind CSS
Setting up Tailwind CSS in a Create React App project.
tailwindcss.com
<div>
<label for="email">email</label>
<input
required
id="email"
type="email"
placeholder="example@gmail.com"
class={inputClassName}
/>
<label for="password">password</label>
<input
placeholder="password"
required
id="password"
type="password"
class={inputClassName}
/>
<label for="intro">ํ์ค ์๊ฐ</label>
<textarea
id="intro"
placeholder="์์ ์ ์๊ฐํด๋ณด์ธ์"
class="mb-4 px-3 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
></textarea>
<button class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
ํ์๊ฐ์
</button>
</div>
tailwind๋ฅผ ์ฌ์ฉํด ๋ง๋ ํ์๊ฐ์ ํผ์ด๋ค.
โ key props
๋ฐฐ์ด์ ์ฌ์ฉํด ์ฌ๋ฌ๊ฐ์ ์์๋ฅผ ๋ง๋ค์ด ๋ผ๋ key props์ ์ฌ์ฉํด์ผํ๋ค๊ณ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์ํค๋๋ฐ, key๋ฅผ ์ฌ์ฉํด์ผํ๋ ์ด์ ๋ virtual DOM๊ณผ real DOM์ ๋น๊ตํด ๋ ๋๋งํ ๋ ์ข ๋ ํจ์จ์ ์ด๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค.
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
์ด๋ ๊ฒ index๋ฅผ ์ฌ์ฉํด, key์ ๋ฃ์์๋ ์์ง๋ง ์ด ๋ฐฉ๋ฒ์ ๊ถ์ฅ๋์ง ์๋๋ค๊ณ ํ๋ค. ๋ง์ฝ text๊ฐ ๋ค๋ฅด๋ค๋ฉด text๋ฅผ ์คํ๋ ค key๋ก ์ฌ์ฉํ๋๊ฒ์ ๊ถ์ฅํ๋ค๊ณ ํ๋ค.
โ๏ธnanoId
์์ ์ค nanoId๋ก key๊ฐ์ ์ฃผ๋๊ฑด ์ด๋ค์ง์ ๋ํ ์ง๋ฌธ์ด ์์๋๋ฐ, state๋ฅผ ํตํด ๋ฆฌ๋ ๋๋ง์ด ๋๋ค๋ฉด ๊ณ์ nanoId๊ฐ์ด ๋ฐ๋๋ฉด์ key๊ฐ ๋ฐ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ key๊ฐ ๋ฐ๋๋ฉด, DOM์ ์ฅ์์ ๋ ๋ ๋๋ง์ด ๋ฐ์ํ๋ฏ๋ก ์ ํฉํ์ง ์๋๋ค๊ณ ํ๋ค.
์ ๋ฒ ์๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์์ฑํ netflexํ์ด์ง ๋ฆฌ์กํธ๋ก ๋ง๋ค๊ธฐ๋ฅผ ํด๋ณด์๋ค
const nowPlaying =
'https://api.themoviedb.org/3/movie/now_playing?language=ko-KR&page=1®ion=KR';
const topRated =
'https://api.themoviedb.org/3/movie/top_rated?language=ko-KR&page=1®ion=KR';
// -- ๋ฐฉ๋ฒ1์ ํ์ --
// const options = {
// method: 'GET',
// headers: {
// accept: 'application/json',
// Authorization:
// 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJkYjdiMTJjM2M2NjhiMjNjZThhNmNhMjFiYTE5M2JjYiIsInN1YiI6IjY1YTlkNjZjNTM0NjYxMDEzOGNkMTFhYiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.SYgTW92CkzlWhUcTXHe5m8wIx6jYWHxLcrTLcMwFbQ4',
// },
// };
// -- ๋ฐฉ๋ฒ2, 3์ ํ์ --
async function getMovies(endpoint) {
const response = await fetch(endpoint);
const data = await response.json();
const movies = data.results;
return movies;
}
function App() {
// -- ๋ฐฉ๋ฒ3 --
const [movies, setMovies] = useState({ nowPlaying: [], topRated: [] });
useEffect(() => {
Promise.all([getMovies(nowPlaying), getMovies(topRated)]).then(
([nowPlaying, topRated]) => setMovies({ nowPlaying, topRated })
);
// -- ๋ฐฉ๋ฒ2์ ํ์ --
// const [nowPlayingMovies, setNowPlayingMovies] = useState([]);
// const [topRatedMovies, setTopRatedMovies] = useState([]);
// -- ๋ฐฉ๋ฒ2 --
// getMovies(nowPlaying).then((movies) => setMovies({ nowPlaying }));
// getMovies(topRated).then((movies) => setMovies({ topRated }));
// -- ๋ฐฉ๋ฒ1 --
// fetch(nowPlaying, options)
// .then((response) => response.json())
// .then((response) => setNowPlayingMovies(response.results))
// .catch((err) => console.error(err));
}, []);
๊ฐ์ฌ๋์ด ์ฝ๋๋ฆฌ๋ทฐ๋ฅผ ํด์ฃผ์๋ฉด์, ๋ค์ํ fetch๋ฐฉ๋ฒ๋ค์ ๋ณด์ฌ์ฃผ์ จ๋๋ฐ, state๋ฅผ ๋ฐ๋ก ๊ด๋ฆฌํ์ง ์๊ณ ๊ฐ์ฒดํํ๋ก ํ๋ฒ์ ๋๊ฐ์ง movie์ ๋ณด๋ฅผ ๊ด๋ฆฌํ๊ณ , Promise.all์ ์ฌ์ฉํด ๋ณ๋ ฌ์ ์ผ๋ก fetchํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ จ๋ค. ์ด๋ ๋งค๊ฐ๋ณ์์ ๊ฐ์ฒด๋ ํ๋ก๋ฏธ์ค์ ๋ฐฐ์ด์ด๋ผ๋๊ฒ์ ์ ์ํ์.