내배캠 TIL 2022.12.09
전역 state를 쓰더라도
간단한 용도로는 부분적으로 부분 state를 쓴다.
키 밸류 값이 같은 경우 하나만 써주기도 하는 듯
export default {}없이 쓸 수 있고
가장 대표로 나가는 값이다.
Ducks 패턴 - redux module 작성방법의 정석
협업자들끼리 구성요소를 빨리 파악하기 위해 정한 패턴
우리는 이미 이 패턴을 따르고 있었다. ㅎㄷㄷ
1. reducer 함수를 export default 한다.
2. action creator 함수들을 export 한다
3. action의 type은 app/reducer/ACTION_TYPE 형태로 작성한다.
(우리는 action type을 상수로 PLUS_ONE 하나만 써줬는데 app/counter/PLUS_ONE 이런식으로 써줘야된다는 말인가?)
module 파일 1개에는 action-type, action creator, reducer가 모두 존재하는 작성방식
React- router-dom
SPA 방식 설정
예전에 바닐라.js로 SPA 웹 페이지 만들었던 것과 원리는 비슷하다.
yarn add react-router-dome
yarn add react-router-dome
여러 페이지의 컴포넌트들을 만들고
router.js에 넣어준다.
import React from "react";
// 1. react-router-dom을 사용하기 위해서 아래 API들을 import 합니다.
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";
//모든 페이지 컴포넌트들 임포트
// 2. Router 라는 함수를 만들고 아래와 같이 작성합니다.
//BrowserRouter를 Router로 감싸는 이유는,
//SPA의 장점인 브라우저가 깜빡이지 않고 다른 페이지로 이동할 수 있게 만들어줍니다!
const Router = () => {
return (
<BrowserRouter>
<Routes>
{/* 컴포넌트들의 url을 정해준다. */}
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
</Routes>
</BrowserRouter>
);
};
export default Router;
App.js에 router를 넣어준다.
import React from "react";
import Router from "./shared/Router"; //라우터 임포트 해준다.
const App = () => {
return <Router />;
// App 컴포넌트 안에 넣어준다.
};
export default App;
App.js는 최상위 컴포넌트로 모든 컴포넌트들이 화면에 띄워지기 전에 거쳐간다.
react-router-dom에서 쓰는 hook
useNavigate(); : 페이지 이동시킬 때 쓴다.
import React from "react";
import { useNavigate } from "react-router-dom";
const Home = () => {
const navigate = useNavigate();
return (
<>
<div>Home</div>
<button
onClick={() => {
navigate("/about");
}}
>
To About
</button>
</>
);
};
useLocation:
-현재 위치하고 있는 페이지의 정보를 얻을 수 있다.
-pathname이 찍힌다
- 조건부 렌더링에 이용할 수 있다)]
Link:
- hook은 아니지만 꼭 알아야하는 api
- HTML의 a 태그를 대체한 것,
- 페이지 이동시킬 때 쓴다.
a 태그를 쓰지 않는 이유
페이지 이동시 브라우저 새로고침 된다.
= 모든 컴포넌트를 다시 렌더링하고, useState와 redux에 메모리상 구축했던 상태값들이 모두 초기화된다.
= 성능에 악영향을 주고, 불필요한 움직임이다.
import React from "react";
import { Link, useLocation } from "react-router-dom";
const About = () => {
const location = useLocation();
console.log(location);
return (
<>
<div>About</div>
<div>{`현재 페이지: ${location.pathname}`}</div>
<Link to="/contact">To Contact</Link>
</>
);
};
export default About;
children을 이용한 layout을 적용해보자
layout 역할을 하는 컴포넌트들에서는 어떤 자식 element들이 들어올지 미리 알 수 없어서 children을 쓴다
컴포지션: 합성이라는 뜻
layout을 만들어서 header와 footer를 합성해보자.
layout 태그가 감싸는 모든 것들이 children이 된다.
항상 header와 footer 중간에 children 들어가도록 지정한다.
router 컴포넌트에서 <BrowserRouter> 태그 바로 아래에 <Layout> 컴포넌트 태그를 넣으면
모든 페이지에 공통으로 layout이 적용된다.
Layout.js
// src/shared/Layout.js
import React from "react";
const HeaderStyles = {
width: "100%",
background: "black",
height: "50px",
display: "flex",
alignItems: "center",
paddingLeft: "20px",
color: "white",
fontWeight: "600",
};
const FooterStyles = {
width: "100%",
height: "50px",
display: "flex",
background: "black",
color: "white",
alignItems: "center",
justifyContent: "center",
fontSize: "12px",
};
const layoutStyles = {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
minHeight: "90vh",
};
function Header() {
return (
<div style={{ ...HeaderStyles }}>
<span>Sparta Coding Club - Let's learn React</span>
</div>
);
}
function Footer() {
return (
<div style={{ ...FooterStyles }}>
<span>copyright @SCC</span>
</div>
);
}
function Layout({ children }) {
return (
<div>
<Header />
<div style={{ ...layoutStyles }}>{children}</div>
<Footer />
</div>
);
}
export default Layout;
Router.js
import React from "react";
// 1. react-router-dom을 사용하기 위해서 아래 API들을 import 합니다.
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";
//모든 페이지 컴포넌트들 임포트
import Layout from "./Layout";
// 2. Router 라는 함수를 만들고 아래와 같이 작성합니다.
//BrowserRouter를 Router로 감싸는 이유는,
//SPA의 장점인 브라우저가 깜빡이지 않고 다른 페이지로 이동할 수 있게 만들어줍니다!
const Router = () => {
return (
<BrowserRouter>
<Layout>
<Routes>
{/* 컴포넌트들의 url을 정해준다. */}
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
</Routes>
</Layout>
</BrowserRouter>
);
};
export default Router;
동적 라우팅 Dynamic Route
const Router = () => {
return (
<BrowserRouter>
<Layout>
<Routes>
{/* 컴포넌트들의 url을 정해준다. */}
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
//url works 이후로 어떤 값이 들어가던지 차이가 없게 해준다.
<Route path="works/:id" element={<Works />} />
</Routes>
</Layout>
</BrowserRouter>
);
};
useParams: 같은 컴포넌트지만 다른 내용물을 보여줄 때 쓰는 Hook