: state와 생명주기 기능에 갈고리를 걸어 원하는 시점에 정해진 함수를 실행되도록 만든 것
state
: 리액트 컴포넌트의 변경 가능한 데이터
= 컴포넌트에 대한 정보를 포함하는 자바스크립트 객체→ state가 바뀔 때마다 리액트는 컴포넌트를 브라우저에 재렌더링
- props와 비교
- 공통점: 컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체
- 차이점: props는 매개변수처럼 컴포넌트에 전달되는 반면, state는 함수 내 지역변수처럼 컴포넌트 안에서 관리됨
: 함수 컴포넌트에서 state를 사용하고 싶을 때 사용
🔎 const [변수명, setter] = useState(초깃값)
import React, { useState } from "react";
function App() {
// count가 변경될 때마다 재렌더링
const [count, setCount] = useState(0);
const countUp = () => setCount(count + 1);
return (
<div>
<p>count: {count}</p>
<button onClick={countUp}>countUp</button>
</div>
);
}
→ 버튼을 누르면 count가 1씩 증가하는 것을 p태그에서 확인 가능
비동기 useState 동기로 처리하기https://parkparkpark.tistory.com/163
: 서버에서 데이터를 받아오거나, DOM을 변경하는 등의 작업을 수행하기 위한 훅
🔎 useEffect(이펙트 함수, 의존성 배열);
의존성 배열 값에 따른 3가지 경우
import React, { useEffect, useState } from "react";
function App() {
const [count, setCount] = useState(0);
const countUp = () => setCount(count + 1);
// count가 변경될 때마다 함수 실행됨
useEffect(() => {
console.log("useEffect ", count);
}, [count]);
return (
<div>
<p>count: {count}</p>
<button onClick={countUp}>countUp</button>
</div>
);
}
→ 버튼을 누르면 count가 1씩 증가하는 것을 p태그 뿐만 아니라, 콘솔에서도 확인할 수 있음
: 연산량이 높은 작업의 반복을 피하기 위해 사용
→ 렌더링이 일어나는 동안 실행됨
→ 이후 의존성 배열 내 변수가 변하면, 값 생성 함수를 호출하여 결괏값 반환
→ 그 외에는 기존 함수의 결괏값 반환
🔎 const 변수명 = useMemo(값 생성 함수, 의존성 배열)
import React, { useMemo } from "react";
function App() {
const value = useMemo(() => doSomething(a, b), [a, b]);
}
: 함수 컴포넌트에서 Context를 쉽게 사용할 수 있게 해주는 훅
Context
: 데이터를 props를 통해 전달할 필요 없이, 필요로 하는 컴포넌트에 바로 전달하는 방식
→ 어떤 컴포넌트든지 컨텍스트의 데이터에 쉽게 접근 가능
🔎 const 변수명 = useContext(사용할 컨텍스트)
import React, { createContext } from "react";
import Children from "./Children";
// Context 객체 생성
export const ParentContext = createContext();
function Parent() {
// 전달할 데이터
const human = {name:"하니", age:20};
return (
<>
<ParentContext.Provider value={human}>
<Children />
</ParentContext.Provider>
</>
);
}
export default Parent;
import React, { useContext } from "react";
import { ParentContext } from "./Parent";
function Children() {
// 데이터 불러오기
const human = useContext(ParentContext);
return (
<>
<p>{human.name}</p>
<p>{human.age}</p>
</>
);
}
export default Children;
: 사용자가 입력한 URL 주소를 감지하는 역할
Routing
: 어떤 네트워크 안에서 통신 데이터를 보낼 때, 최적의 경로를 선택하는 과정
= 네트워크 상에서 URL을 이용했을 때 어떤 경로를 이용해서 데이터를 받아올 건지 결정해주는 것
= 사용자가 URL을 요청했을 때 어떤 페이지로 연결할 것인지 결정하는 매커니즘
SPA를 사용할 때 사용자가 페이지를 북마크하기 어렵고,
브라우저 상에서 뒤로가기·앞으로가기와 같은 네비게이션이 추가되지 않는 문제점을 해결하기 위해 React Router가 등장하였다.
react-router-dom은 URL에 따라 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리
→ npm install --save react-router-dom
import { BrowserRouter, Link, Route, Routes, useNavigate, useParams, useSearchParams } from "react-router-dom";
<BrowserRouter>
컴포넌트 내 <Routes>
태그를 넣고, path마다 어떤 컴포넌트를 보여줄건지 작성한 <Route>
태그를 생성
→ 라우터(BrowserRouter)는 앱에서 단 하나만 사용해야 함
페이지를 갱신하지 않고 렌더링 방식으로 이동하기 위해 <Link>
컴포넌트를 사용
→ 클릭 시 HTML anchor 태그로 자동으로 변환되고 URL이 변경됨
<BrowserRouter>
<Link to="/경로?쿼리스트링=값">이동</Link>
<Routes>...</Routes>
</BrowserRouter>
Link 는 클릭 시 특정 주소로 이동해주는 태그였다면,
Navigate 는 특정 행동을 했을 때 해당 주소로 이동
🔎 생성 : const 함수명 = useNavigate()
🔎 사용 : 함수명('주소', {})
함수의 인자 args
첫 번째 인자로는 주소를 받으며
두 번째 인자로 replace, state 인수를 사용
navigate('경로', {state: 상태})
로 state를 넘겨주고,const 변수명 = useLocation()
로 state를 받을 수 있음useHistory의 기능도 포함 (window의 history를 이용한 navigate 기능)
→ 세션 기록(페이지 방문 기록)에 대한 접근 방법과 메서드를 제공
<Navigate to="/login" />
대신 useNavigate 사용 권장
Note: This API is mostly useful in React.Component subclasses that are not able to use hooks. In functional components, we recommend you use the useNavigate
hook instead.
// 생성
const navigate = useNavigate();
// 사용 예시1
navigate("원하는 주소", {replace: true});
// 사용 예시2
<button onClick={() => navigate(-1)}>
Go back
</button>
let {파라미터명} = useParams()
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/users/:id" exact element={<User />} />
<Routes/>
<BrowserRouter/>
);
}
function User() {
// id로 쓰인 path 변수 받기
let {id} = useParams();
return <p>ID: {id}</p>
}
exact
: 의도치 않은 렌더링을 막기 위해exact
카워드 사용
Route
는 경로가 부분적으로 일치하는 컴포넌트도 렌더링하는 특성을 가지고 있기 때문
<Link>
에 따로 명시를 하지 않아도 됨const [변수명, setter] = useSearchParams()
const [searchParams, setSearchParams] = useSearchParams();
// Query String 얻기
const seq = searchParams.get('seq');
// Query String 변경
<button onClick={() => setSearchParams({ name: "hani" })}>name 바꾸기</button>
App.js
import { BrowserRouter, Link, Route, Routes, useParams } from "react-router-dom";
function App() {
return (
<div>
<BrowserRouter>
<nav>
<span>
<Link to="/">Home</Link>
</span>
<span>
<Link to="/about">About</Link>
</span>
<span>
<Link to="/topics">Topics</Link>
</span>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/topics" element={<Topics />} />
<Route path="/topics/:topicId" exact element={<Topic />} />
</Routes>
</BrowserRouter>
</div>
);
}
function Home() {
return <h1>Home</h1>
}
function About() {
return <h2>About</h2>
}
function Topics() {
return (
<div>
<h3>Topics</h3>
<ul>
<li><Link to="/topics/components">components</Link></li>
<li><Link to="/topics/props">props</Link></li>
</ul>
</div>
);
}
function Topic() {
let {topicId} = useParams();
return <h4>Topic ID: {topicId}</h4>
}
export default App;
→ 링크를 누르면 페이지 이동