[React] 훅 Hook & 라우터 Router

sua_ahn·2023년 3월 29일
0

React

목록 보기
4/6
post-thumbnail

Hook

: state와 생명주기 기능에 갈고리를 걸어 원하는 시점에 정해진 함수를 실행되도록 만든 것

state

: 리액트 컴포넌트의 변경 가능한 데이터
= 컴포넌트에 대한 정보를 포함하는 자바스크립트 객체

→ state가 바뀔 때마다 리액트는 컴포넌트를 브라우저에 재렌더링

  • props와 비교
    • 공통점: 컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체
    • 차이점: props는 매개변수처럼 컴포넌트에 전달되는 반면, state는 함수 내 지역변수처럼 컴포넌트 안에서 관리됨

 

useState()

: 함수 컴포넌트에서 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

 

useEffect()

: 서버에서 데이터를 받아오거나, 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태그 뿐만 아니라, 콘솔에서도 확인할 수 있음

 

useMemo()

: 연산량이 높은 작업의 반복을 피하기 위해 사용

→ 렌더링이 일어나는 동안 실행됨
→ 이후 의존성 배열 내 변수가 변하면, 값 생성 함수를 호출하여 결괏값 반환
→ 그 외에는 기존 함수의 결괏값 반환

🔎 const 변수명 = useMemo(값 생성 함수, 의존성 배열)

import React, { useMemo } from "react";

function App() {
  
  const value = useMemo(() => doSomething(a, b), [a, b]); 
}

 

useContext()

: 함수 컴포넌트에서 Context를 쉽게 사용할 수 있게 해주는 훅

Context

: 데이터를 props를 통해 전달할 필요 없이, 필요로 하는 컴포넌트에 바로 전달하는 방식
→ 어떤 컴포넌트든지 컨텍스트의 데이터에 쉽게 접근 가능

🔎 const 변수명 = useContext(사용할 컨텍스트)

  • useContext를 사용하기 위해 context API에 대해 알아보자!
    • createContext : context 객체를 생성
    • Provider : 생성한 context를 하위 컴포넌트에게 전달하는 역할
    • Consumer : context의 변화를 감시하는 컴포넌트

Parent.js

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;

Children.js

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;

 


React Router

: 사용자가 입력한 URL 주소를 감지하는 역할

 

Routing

: 어떤 네트워크 안에서 통신 데이터를 보낼 때, 최적의 경로를 선택하는 과정

= 네트워크 상에서 URL을 이용했을 때 어떤 경로를 이용해서 데이터를 받아올 건지 결정해주는 것

= 사용자가 URL을 요청했을 때 어떤 페이지로 연결할 것인지 결정하는 매커니즘

 

등장

SPA를 사용할 때 사용자가 페이지를 북마크하기 어렵고,
브라우저 상에서 뒤로가기·앞으로가기와 같은 네비게이션이 추가되지 않는 문제점을 해결하기 위해 React Router가 등장하였다.

 

설정

1. 라이브러리 설치

react-router-dom은 URL에 따라 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리

npm install --save react-router-dom

2. import

import { BrowserRouter, Link, Route, Routes, useNavigate, useParams, useSearchParams } from "react-router-dom";

3. BrowserRouter 컴포넌트

<BrowserRouter> 컴포넌트 내 <Routes> 태그를 넣고, path마다 어떤 컴포넌트를 보여줄건지 작성한 <Route> 태그를 생성

→ 라우터(BrowserRouter)는 앱에서 단 하나만 사용해야 함

 

Routing 기능

페이지를 갱신하지 않고 렌더링 방식으로 이동하기 위해 <Link> 컴포넌트를 사용

→ 클릭 시 HTML anchor 태그로 자동으로 변환되고 URL이 변경됨

<BrowserRouter>
  <Link to="/경로?쿼리스트링=값">이동</Link>
  
  <Routes>...</Routes>
</BrowserRouter>

2. useNavigate() 이동

Link 는 클릭 시 특정 주소로 이동해주는 태그였다면,
Navigate 는 특정 행동을 했을 때 해당 주소로 이동

🔎 생성 : const 함수명 = useNavigate()
🔎 사용 : 함수명('주소', {})

  • 함수의 인자 args
    첫 번째 인자로는 주소를 받으며
    두 번째 인자로 replace, state 인수를 사용

    • replace
      false : 기본값. 뒤로가기 가능
      true : 뒤로가기 시 메인 페이지("/")로 이동
    • 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>

3. URL 제어

  • Path Variable (URL 파라미터)
    • 콜론(:)과 useParams hook을 이용해 URL 파라미터를 받을 수 있음
      🔎 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는 경로가 부분적으로 일치하는 컴포넌트도 렌더링하는 특성을 가지고 있기 때문

  • Query String
    • 라우팅에 영향을 끼치지 않기 때문에 <Link>에 따로 명시를 하지 않아도 됨
    • useSearchParams hook을 사용해 값을 확인할 수 있음
      🔎 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>&nbsp;&nbsp;
          </span>
          <span>
            <Link to="/about">About</Link>&nbsp;&nbsp;
          </span>
          <span>
            <Link to="/topics">Topics</Link>&nbsp;&nbsp;
          </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;

→ 링크를 누르면 페이지 이동

profile
해보자구

0개의 댓글