๐ธ Lint
Lint๋ ์ฝ๋ ์คํ์ผ๊ณผ ๋ฌธ๋ฒ ์ค๋ฅ๋ฅผ ๊ฒ์ฌํ๊ณ ์ผ๊ด๋ ์ฝ๋๋ฅผ ์ ์งํ๊ฒ ๋์์ฃผ๋ ๋๊ตฌ
lint ์คํ : ํ์ฌ ๋๋ ํ ๋ฆฌ(.)๋ถํฐ ๋ชจ๋ ํ์ผ์ ESLint๋ก ๊ฒ์ฌ
- ์ฝ๋ ์คํ์ผ ๊ฒ์ฌ ๋ฐ ์๋ ์์
- ํ์
ํ ๋ ์ฝ๋ ํ๋ฆฌํฐ ์ ์ง์ ๋์๋จ
๐ธ React Router
- React์์ ํ์ด์ง ์ ํ์ ์ฒ๋ฆฌํ๋ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- SPA(Single Page Application)์์ URL์ ๋ฐ๋ผ ํ๋ฉด์ ๋ฐ๊พธ๋ ์ญํ !
๋ผ์ฐํ
- URL์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฝํ
์ธ ๋ฅผ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ
- ์์ ๋ฐฉ์: URL ์์ฒญ ์ ์๋ฒ์์ ์ HTML ํ์ผ ์ ๋ฌ
example.com/home
โ ์๋ฒ์ home.html ํ์ผ ์์ฒญexample.com/about
โ ์๋ฒ์ about.html ํ์ผ ์์ฒญ
- SPA: ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ํ์ด์ง ์ ํ ์์ด ํ๋ฉด๋ง ๊ต์ฒด (๋น ๋ฆ!)
ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ
React ๊ฐ์ SPA์์ ๋ผ์ฐํ
์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ ํ์ด์ง๋ฅผ ์์ฒญํ์ง ์๊ณ , ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ URL๊ณผ ํ๋ฉด์ ์ ์ดํ๋ ๋ฐฉ์
๋์ ์๋ฆฌ
- ์ด๊ธฐ ๋ก๋ฉ ์: ํ์ํ ๋ชจ๋ JS ํ์ผ์ ํ ๋ฒ์ ๋ค์ด๋ก๋
- URL์ด ๋ฐ๋ ๋:
- ์๋ฒ์ ์๋ก์ด HTML์ ์์ฒญ โ
- ๋ธ๋ผ์ฐ์ ์ History API (pushState, replaceState)๋ฅผ ์ฌ์ฉํด URL๋ง ๋ฐ๊ฟ
- React Router๊ฐ URL์ ๋ฐ๋ผ ์ปดํฌ๋ํธ๋ฅผ ๊ต์ฒดํจ
- ๊ฒฐ๊ณผ์ ์ผ๋ก ํ๋ฉด ๊น๋นก์ ์์ด ๋น ๋ฅธ ์ ํ์ด ๊ฐ๋ฅ!
์ค์น
๊ตฌํ ๋ฐฉ์
1๏ธโฃ createBrowserRouter + <RouterProvider>
1
2
| // router์ ๊ด๋ จ๋๊ฑฐ๋ฅผ ํ๊ณณ์ ๋ชจ์๋๋๊ฒ ์ข์
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // routes/index.jsx
const router = createBrowserRouter([
{
element: <Default />,
children: [
{
path: "/",
element: <MainPage />, // ๋ถ๋ชจ
children: [{ path: "", element: <MainSub1Page /> }], // ์์ ํ์ด์ง ๋ชฉ๋ก
},
{ path: "/about", element: <AboutPage /> },
],
},
{ path: "*", element: <NotFound /> },
]);
export default function Router() {
return <RouterProvider router={router} />;
}
|
โ
ํน์ง:
- React Router v6.4 ์ด์๋ถํฐ ์ง์ํ๋ ์๋ก์ด ๋ฐฉ์
- JS ๊ฐ์ฒด๋ก ๋ผ์ฐํฐ ๊ตฌ์ฑ โ ์ ์ง๋ณด์ ์ฌ์
- ๋ฐ์ดํฐ ๋ก๋ฉ, ์๋ฌ ์ฒ๋ฆฌ ๋ฑ ๊ธฐ๋ฅ ํ์ฅ์ ์ ๋ฆฌ
- ์ข ๋ ๊ตฌ์กฐ์ ์ด๊ณ ๋๊ท๋ชจ ํ๋ก์ ํธ์ ์ ํฉ
createBrowserRouter โ RouterProvider๋ก ์ฐ๊ฒฐ
2๏ธโฃ <BrowserRouter>
+ <Routes>
1
2
3
4
5
| <BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</BrowserRouter>
|
โ
ํน์ง:
- ์๋ ๋ถํฐ ์ฐ๋ ์ ํต์ ์ธ ๋ฐฉ์
- JSX ์์์ ์ง์
<Route>
๋ก ์์ฑ - ๊ฐ๋จํ ํ๋ก์ ํธ์ ์ ํฉ
<BrowserRouter>
โ <Routes>
โ <Route>
๋ก ํธ๋ฆฌ ๊ตฌ์กฐ
Link ์ปดํฌ๋ํธ
<Link>
์ปดํฌ๋ํธ๋ ํ์ด์ง ์ ์ฒด๋ฅผ ์๋ก๊ณ ์นจํ์ง ์๊ณ ํด๋ผ์ด์ธํธ์์ ํ๋ฉด ์ ํ
1
| import { Link } from 'react-router-dom'
|
1
| <Link to="/about">About</Link>
|
NavLink ์ปดํฌ๋ํธ
<NavLink>
์ปดํฌ๋ํธ๋ ํ์ฌ ๊ฒฝ๋ก์ ์ผ์นํ ๋ ์๋์ผ๋ก active ํด๋์ค๋ฅผ ์ถ๊ฐactive
๊ฐ ๋ถ์ด์ ์๊ฐ์ ์ผ๋ก ํํํ๊ธฐ ํธํจ
1
2
3
4
5
| <NavLink
to="/"
className={({ isActive }) => (isActive ? styles.active : '')}>
Home
</NavLink>
|
<Outlet />
: ์์ ๋ผ์ฐํธ ํ์ ์๋ฆฌ
- children์ด ๋ค์ด๊ฐ ์์น๋ผ๋๊ฒ์ ์ค์
- ์์ ๋ผ์ฐํธ๋ฅผ ๋ ๋๋งํ๋ ์๋ฆฌ
- ๋ถ๋ชจ ์ปดํฌ๋ํธ ์์
<Outlet />
์ ๋ฃ์ผ๋ฉด, ํ์ฌ ๋งค์นญ๋ ์์ ๊ฒฝ๋ก์ ์ปดํฌ๋ํธ๊ฐ ํ์๋จ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| import React from "react";
import { Outlet } from "react-router-dom";
import Footer from "../../components/Footer";
import Header from "../../components/Header";
const Default = () => {
return (
<>
<Header />
<Outlet /> {/* ์ฌ๊ธฐ์ ์์ ์ปดํฌ๋ํธ ๋ ๋๋จ */}
<Footer />
</>
);
};
export default Default;
|
์ค๋ฌด์์ ๋ง์ด ์ฐ๋ ํด๋ ๊ตฌ์กฐ
1
2
3
4
5
6
7
8
9
| src/
โโโ pages/
โโโ AboutPage/
โโโ AboutPage.jsx
โโโ AboutPage.module.css
โโโ useAboutData.js
โโโ AboutService.js
โโโ components/
โโโ AboutCard.jsx
|
- ๊ฐ ํ์ด์ง๋ณ๋ก ํด๋ ๊ด๋ฆฌ โ ๊ธฐ๋ฅ ํ์ฅ, ์ ์ง๋ณด์ ํธํจ
- ์คํ์ผ, API, ์ปดํฌ๋ํธ๊น์ง ํ ํด๋์ ๋ชจ์
๐ธ swiper
์คํ์ผ์ ๊ตฌ์กฐ์ ์ ๊ทผ
์ฌ๋ผ์ด๋ ๋ด๋ถ ๊ตฌ์กฐ๊ฐ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํด ์ ์ด๋๋ ๊ฒฝ์ฐ, ์ง์ ํด๋์ค๋ฅผ ์ค ์ ์์ผ๋ฏ๋ก ๊ตฌ์กฐ์ ์ผ๋ก ์ ๊ทผํด ์คํ์ผ์ ์ปค์คํฐ๋ง์ด์งํจ.
1
2
3
| .slider > div > div {
background-color: #9f9f9f;
}
|
๐ก Swiper๋ ๋ด๋ถ ๊ตฌ์กฐ๊ฐ .swiper > .swiper-wrapper > .swiper-slide
์ฒ๋ผ ๊ตฌ์ฑ๋จ
onSwiper + useRef๋ก Swiper ์ง์ ์กฐ์ํ๋ ๋ฐฉ๋ฒ
๐ก ์ธ์ ์ฐ๋?
- Swiper์ ๊ธฐ๋ณธ ๋ด๋น๊ฒ์ด์
๋ฒํผ์ด ์๋, ๋ด๊ฐ ๋ง๋ ์ปค์คํ
๋ฒํผ์ผ๋ก ์ฌ๋ผ์ด๋๋ฅผ ๋๊ธฐ๊ณ ์ถ์ ๋
- ๋๋ ์ฌ๋ผ์ด๋๋ฅผ ํ๋ก๊ทธ๋๋ฐ์ ์ผ๋ก ์ ์ดํ๊ณ ์ถ์ ๋
๐ง ํ๋ฆ ์์ฝ
๋จ๊ณ | ์ค๋ช
|
---|
1. useRef() | Swiper ์ธ์คํด์ค๋ฅผ ๋ด์๋ ๋น ๋ณ์(๊ทธ๋ฆ) ์์ฑ (null๋ก ์์) |
2. onSwiper | Swiper๊ฐ ์ฒ์ ๋ง๋ค์ด์ง ๋, ์ธ์คํด์ค๋ฅผ ref.current ์ ์ ์ฅ |
3. ๋ฒํผ ํด๋ฆญ | ref.current.slidePrev() ๋๋ .slideNext() ํธ์ถํด์ ์ฌ๋ผ์ด๋ ์ ์ด |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| import { useRef } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
export default function CustomSwiper() {
const swiperRef = useRef(null); // Swiper ์ธ์คํด์ค ๋ด์ ref ์์ฑ
return (
<div>
<Swiper
// Swiper๊ฐ ์ค๋น๋๋ฉด ๊ทธ ์ธ์คํด์ค๋ฅผ swiperRef.current ์ ๋ด๊ธฐ
onSwiper={(swiper) => (swiperRef.current = swiper)}
slidesPerView={1}
spaceBetween={10}
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
</Swiper>
{/* ์ปค์คํ
๋ฒํผ ํด๋ฆญ ์, ํด๋น ๋ฉ์๋๋ฅผ ์ง์ ํธ์ถํด์ ์ฌ๋ผ์ด๋๋ฅผ ์ ์ด */}
<button onClick={() => swiperRef.current.slidePrev()}>Prev</button>
<button onClick={() => swiperRef.current.slideNext()}>Next</button>
</div>
);
}
|
๐ Swiper ์ธ์คํด์ค์์ ์ธ ์ ์๋ ๋ํ ๋ฉ์๋
๋ฉ์๋ | ์ค๋ช
|
---|
slideNext() | ๋ค์ ์ฌ๋ผ์ด๋๋ก ์ด๋ |
slidePrev() | ์ด์ ์ฌ๋ผ์ด๋๋ก ์ด๋ |
slideTo(index) | ํน์ ์ธ๋ฑ์ค๋ก ์ด๋ |
autoplay.start() | ์๋ ์ฌ์ ์์ |
autoplay.stop() | ์๋ ์ฌ์ ์ ์ง |
๐ธ useRef
- ๋ฆฌ๋ ๋๋ง ์์ด ๊ฐ์ ์ ์ฅํ ์ ์๋ React์ ๋น๋ฐ ์์
- ๊ฐ์ด ๋ฐ๋์ด๋ ํ๋ฉด์ด ์ ๋ฐ๋ (โ
useState
์ ๋ค๋ฆ) ref.current
๋ก ๊ฐ ์ฝ๊ณ , ์ธ ์ ์์
๋ํ์ ์ธ ์ฌ์ฉ ์ฌ๋ก
์ํฉ | ์์ |
---|
DOM ์ง์ ์ ์ด | ๋ฒํผ ํด๋ฆญ ์ input์ focus ์ฃผ๊ธฐ ๋ฑ |
ํ์ด๋จธ / interval ID ์ ์ฅ | setTimeout , setInterval ๊ด๋ฆฌ |
Swiper ๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ธ์คํด์ค ์ ์ฅ | swiperRef.current.slideNext() |
๋ฆฌ๋ ๋๋ง ์์ด ๊ฐ ์ ์ง | ์ด์ props ๊ธฐ์ต, ์นด์ดํฐ ์ถ์ ๋ฑ |
ํต์ฌ ํน์ง
โ
1. ๋ฆฌ๋ ๋๋ง ๋ฐ์ ์ ํจ
ref.current = ๊ฐ
์ผ๋ก ๋ฐ๊ฟ๋ ํ๋ฉด์ ์ํฅ ์์
โ
2. ๋ ๋๋ง ๊ฐ ๊ฐ์ด ์ ์ง๋จ
- ์ผ๋ฐ ๋ณ์๋ ์ปดํฌ๋ํธ๊ฐ ๋ค์ ์คํ๋๋ฉด ์ด๊ธฐํ๋์ง๋ง
ref
๋ ์ปดํฌ๋ํธ๊ฐ ์ด์์๋ ๋์ ๊ฐ์ด ์ ์ง๋จ
โ
3. DOM ์ง์ ์ ๊ทผ ๊ฐ๋ฅ
1
2
3
| const inputRef = useRef();
<input ref={inputRef} />;
inputRef.current.focus(); // DOM ์ง์ ์ ์ด
|
โ์ฃผ์ํ ์
- ๋ ๋๋ง ์ค์๋ ref.current๋ฅผ ์ฝ๊ฑฐ๋ ์ฐ์ง ๋ง์ธ์
- ๋ ๋๋ง ์ค
ref.current
๋ณ๊ฒฝ์ React ์์ ํจ์ ์์น์ ๊นธ - ์ด๋ฒคํธ ํธ๋ค๋ฌ๋
useEffect
์์์ ์ฌ์ฉํด์ผ ์์
- UI์ ๋ณด์ฌ์ค ๊ฐ์
useState
๋ฅผ ์ฐ์ธ์ref
๋ ํ๋ฉด์ ๋ฐ์๋์ง ์๊ธฐ ๋๋ฌธ!
- ์ด๊ธฐํ๊ฐ ๋ฌด๊ฑฐ์ด ๊ฐ์ ์กฐ๊ฑด๋ถ ์ด๊ธฐํ
1
2
3
| if (ref.current === null) {
ref.current = new VideoPlayer();
}
|
useState
vs useRef
ํญ๋ชฉ | useState | useRef |
---|
๊ฐ์ด ๋ฐ๋๋ฉด ๋ฆฌ๋ ๋๋ง? | โญ๏ธ | โ |
ํ๋ฉด์ ํ์๋๋ ๊ฐ? | โญ๏ธ | โ |
DOM ์ ๊ทผ ๊ฐ๋ฅ? | โ | โญ๏ธ |
๋ ๋๋ง๊ณผ ์๊ด์๋ ๊ฐ ์ ์ฅ | โ | โญ๏ธ |
END