<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Teon.log</title>
        <link>https://velog.io/</link>
        <description>웹 개발자를 향하여</description>
        <lastBuildDate>Tue, 26 Apr 2022 12:39:16 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Teon.log</title>
            <url>https://velog.velcdn.com/images/sparkling0_0/profile/0698f332-3919-41b1-81dd-7dafda867e10/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Teon.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sparkling0_0" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[React Router(v6) 사용하기]]></title>
            <link>https://velog.io/@sparkling0_0/2.-React-Routerv6-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@sparkling0_0/2.-React-Routerv6-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 26 Apr 2022 12:39:16 GMT</pubDate>
            <description><![CDATA[<p>리액트 라우터(v6)를 사용해 아래와 같은 간단한 프로젝트를 만들어보겠습니다.</p>
<p>[미리보기]
<img src="https://velog.velcdn.com/images/sparkling0_0/post/3808037d-5254-4c42-94dc-327378bf4a64/image.png" width="450"/>
<img src="https://velog.velcdn.com/images/sparkling0_0/post/13349a9b-cbb7-427c-841f-a12d90507b48/image.png" width="450"/></p>
<h1 id="1-프로젝트-생성-및-라이브러리-설치">1. 프로젝트 생성 및 라이브러리 설치</h1>
<p><strong>리액트 프로젝트 생성하기</strong></p>
<pre><code class="language-bash">$ yarn create react-app practice_router</code></pre>
<p><strong>라우터 라이브러리 설치하기</strong></p>
<pre><code class="language-bash">$ npm install react-router-dom@6</code></pre>
<p><strong>설치 확인하기</strong>
package.json에 react-router-dom이 잘 설치되어있는지 확인해봅시다.</p>
<pre><code class="language-json">&quot;dependencies&quot;: {
    &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
    &quot;@testing-library/react&quot;: &quot;^13.0.0&quot;,
    &quot;@testing-library/user-event&quot;: &quot;^13.2.1&quot;,
    &quot;react&quot;: &quot;^18.0.0&quot;,
    &quot;react-dom&quot;: &quot;^18.0.0&quot;,
    &quot;react-router-dom&quot;: &quot;^6.3.0&quot;,
    &quot;react-scripts&quot;: &quot;5.0.1&quot;,
    &quot;web-vitals&quot;: &quot;^2.1.0&quot;
},</code></pre>
<h1 id="2-프로젝트에-라우터-적용하기">2. 프로젝트에 라우터 적용하기</h1>
<p>React Router를 적용하기 위해선 가장 먼저 src/index.js 파일의 <code>&lt;App /&gt;</code> 컴포넌트를 <code>&lt;BrowserRouter&gt;</code>로 감싸줘야 합니다.</p>
<pre><code class="language-javascript">import { BrowserRouter } from &quot;react-router-dom&quot;;

const root = ReactDOM.createRoot(document.getElementById(&quot;root&quot;));
root.render(
  &lt;BrowserRouter&gt;
    &lt;App /&gt;
  &lt;/BrowserRouter&gt;
);</code></pre>
<h1 id="3-필요한-컴포넌트-페이지-만들기">3. 필요한 컴포넌트 페이지 만들기</h1>
<p>프로젝트 실습에 필요한 2개의 컴포넌트 페이지를 만들어 보겠습니다.</p>
<p>src폴더 밑에 pages폴더를 새로 생성하고 home.js와 movies.js 파일을 생성해주세요</p>
<p>📄<strong>pages/Home.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;

const Home = () =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;LIKELION React Course&lt;/h1&gt;
      &lt;p&gt;리액트 라우터 실습 프로젝트입니다.&lt;/p&gt;
    &lt;/div&gt;
  );
};

export default Home;
</code></pre>
<p>📄<strong>pages/Movies.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;

const Movies = () =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;넷플릭스 영화 추천 목록&lt;/h1&gt;
    &lt;/div&gt;
  );
};

export default Movies;

</code></pre>
<h1 id="3-route-컴포넌트로-특정-주소에-컴포넌트-연결하기">3. Route 컴포넌트로 특정 주소에 컴포넌트 연결하기</h1>
<p>기존에 있는 App.js 안의 코드를 모두 삭제하고 함수형 컴포넌트로 새로 생성해줍니다.
📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &#39;react&#39;;

const App = () =&gt; {
  return (
    &lt;div&gt;

    &lt;/div&gt;
  );
};

export default App;</code></pre>
<p>react-router-dom의 Routes와 Route 컴포넌트를 사용할 것입니다.
Routes안에 Route 컴포넌트를 사용합니다.</p>
<p>** Route 사용법 **</p>
<pre><code class="language-javascript">&lt;Route path=&quot;주소규칙&quot; element={보여 줄 컴포넌트} /&gt;</code></pre>
<p>Home과 Movies 컴포넌트를 각각 /home, /movies 주소로 연결해보겠습니다.</p>
<p>📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./pages/Home&quot;;
import Movies from &quot;./pages/Movies&quot;;

const App = () =&gt; {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;
      &lt;Route path=&quot;/movies&quot; element={&lt;Movies /&gt;} /&gt;
    &lt;/Routes&gt;
  );
};

export default App;
</code></pre>
<p>각 주소로 접속했을 때 해당 컴포넌트가 잘 보이나요?
<a href="http://localhost:3000/">http://localhost:3000/</a>
<a href="http://localhost:3000/movies">http://localhost:3000/movies</a></p>
<h1 id="4-navbar-만들고-link-컴포넌트로-다른-페이지-이동하기">4. Navbar 만들고 Link 컴포넌트로 다른 페이지 이동하기</h1>
<p>Navbar를 만들어 페이지를 이동해보도록 하겠습니다.</p>
<p>pages폴더에 Menubar.js 파일을 새로 만들어주세요
📄<strong>pages/Menubar.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;

const Menubar = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        &lt;li&gt;Home&lt;/li&gt;
        &lt;li&gt;Movies&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  );
};

export default Menubar;
</code></pre>
<blockquote>
<p><strong>Quiz )</strong>
App.js에 Menubar 컴포넌트를 import 시키고, Menubar 주소는 root로 Home의 주소는 &#39;/home&#39;으로 바꿔보세요</p>
</blockquote>
<p>📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./pages/Home&quot;;
import Movies from &quot;./pages/Movies&quot;;
import Menubar from &quot;./pages/Menubar&quot;;

const App = () =&gt; {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;/&quot; element={&lt;Menubar /&gt;} /&gt;
      &lt;Route path=&quot;/home&quot; element={&lt;Home /&gt;} /&gt;
      &lt;Route path=&quot;/movies&quot; element={&lt;Movies /&gt;} /&gt;
    &lt;/Routes&gt;
  );
};

export default App;

</code></pre>
<p>Navbar의 목록들을 눌러 해당 컴포넌트로 이동하고 싶을 때는 React-router의 Link 컴포넌트를 사용하면 됩니다.</p>
<p>** Link 사용법 **</p>
<pre><code class="language-javascript">&lt;Link to =”주소”&gt;&lt;/Link&gt;</code></pre>
<p>기존에 a링크 쓰듯이 사용하면 됩니다.
a링크와 다른 점은 페이지 전환을 방지하는 기능이 내장되어 있다는 점입니다.</p>
<p>📄<strong>pages/Menubar.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Link } from &quot;react-router-dom&quot;;

const Menubar = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/home&quot;&gt;Home&lt;/Link&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/movies&quot;&gt;Movies&lt;/Link&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  );
};

export default Menubar;
</code></pre>
<p>잘 이동되는지 확인해봅시다.</p>
<h1 id="5-navbar를-페이지들의-공통-레이아웃-컴포넌트로-만들기">5. Navbar를 페이지들의 공통 레이아웃 컴포넌트로 만들기</h1>
<p>Home과 Movies 페이지 위에 Navbar를 두어 페이지를 편하게 이동하도록 해보겠습니다.</p>
<p>물론, Home과 Movies 컴포넌트에 Menubar 컴포넌트를 각각 불러오는 방법도 있겠지만, 
보여줘야 할 페이지들이 많아질 때는 비효율적일 것입니다.</p>
<p>따라서 저희는 Route의 중첩 경로를 이용하여 위의 기능을 구현해보겠습니다.</p>
<p>📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./pages/Home&quot;;
import Movies from &quot;./pages/Movies&quot;;
import Menubar from &quot;./pages/Menubar&quot;;

const App = () =&gt; {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;/&quot; element={&lt;Menubar /&gt;}&gt;
        &lt;Route path=&quot;/home&quot; element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/movies&quot; element={&lt;Movies /&gt;} /&gt;
      &lt;/Route&gt;
    &lt;/Routes&gt;
  );
};

export default App;

</code></pre>
<p>상위 라우트는 Menubar를, 하위라우트는 Home과 Movies를 불러오도록 중쳡경로를 설정하였습니다.</p>
<p>실행화면을 보면 Home과 Movies 주소로 이동해도 Menubar만 보입니다.
상위 라우터 밑에 하위라우트의 element를 보여주고 싶을 때는 Outlet이라는 컴포넌트를 사용합니다.</p>
<p>📄<strong>pages/Menubar.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Link, Outlet } from &quot;react-router-dom&quot;;

const Menubar = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/home&quot;&gt;Home&lt;/Link&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/movies&quot;&gt;Movies&lt;/Link&gt;
        &lt;/li&gt;
      &lt;/ul&gt;

      &lt;Outlet /&gt;
    &lt;/div&gt;
  );
};

export default Menubar;

</code></pre>
<p>이제 실행화면을 다시 보면 각 경로별로 컴포넌트들이 잘 보여지게 됩니다.</p>
<p>❗<strong>여기서 잠깐</strong>
&#39;/&#39;(루트) 경로를 입력해보면 어떠한 하위라우트도 보여지고 있지 않습니다. 
중첩 라우트를 사용할 때, 상위라우트에서 가장 먼저 보여질 하위라우트를 따로 지정해주는 것이 필요한데요.
이때는 index라는 props를 설정해주면 됩니다.</p>
<p>가장 먼저 보여질 하위라우트를 Home으로 설정해보겠습니다.
📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./pages/Home&quot;;
import Movies from &quot;./pages/Movies&quot;;
import Menubar from &quot;./pages/Menubar&quot;;

const App = () =&gt; {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;/&quot; element={&lt;Menubar /&gt;}&gt;
        &lt;Route index element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/movies&quot; element={&lt;Movies /&gt;} /&gt;
      &lt;/Route&gt;
    &lt;/Routes&gt;
  );
};

export default App;

</code></pre>
<p>이제 &#39;/&#39;루트 경로로 들어가면 Menubar와 Home 컴포넌트가 동시에 보이게 됩니다. 
Home의 경로가 달라졌으니 Menubar에서 Link 컴포넌트로 지정해준 Home의 경로도 수정해주세요.
📄<strong>pages/Menubar.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Link } from &quot;react-router-dom&quot;;

const Menubar = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/&quot;&gt;Home&lt;/Link&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/movies&quot;&gt;Movies&lt;/Link&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  );
};

export default Menubar;
</code></pre>
<h1 id="6-url-파라미터-사용하기">6. URL 파라미터 사용하기</h1>
<p>페이지 주소를 정의할 때는 유동적인 값을 사용할 때도 있습니다.
이때는 파라미터와 쿼리 스트링으로 나뉩니다.</p>
<ul>
<li>URL 파라미터 예시 : /movies/1</li>
<li>쿼리스트링 예시 : /movies/1?detail=true</li>
</ul>
<p>일반적으로 URL 파라미터는 특정 아이디 혹은 이름을 사용하여 조회할 때 사용하고,
쿼리스트링은 키워드 검색, 페이지네이션, 옵션 전달 등에 사용합니다.</p>
<h2 id="61-데이터-생성">6.1 데이터 생성</h2>
<p>실습을 위해 src폴더 밑에 넷플릭스 추천 영화 데이터를 모아둘 movie_data.js파일을 생성해주세요.
📄<strong>src/movie_data.js</strong></p>
<pre><code class="language-javascript">let movies = [
  {
    id: 1,
    title: &quot;하울의 움직이는 성&quot;,
    director: &quot;미야자키 하야오&quot;,
    category: &quot;일본 애니메이션&quot;,
    detail:
      &quot;아버지가 물려준 모자 기계를 지키는 수수한 소녀 소피. 전쟁도, 미녀의 심장을 노리는 마법사의 소문도 먼 세상 이야기일 뿐. 하지만 마녀의 저주로 할머니가 되면서, 소피의 인생이 회전목마처럼 힘차게 움직이기 시작한다.&quot;,
  },
  {
    id: 2,
    title: &quot;보스 베이비2&quot;,
    director: &quot;톰 맥그라스&quot;,
    category: &quot;미국 애니메이션&quot;,
    detail:
      &quot;각자의 삶을 살아가던 두 형제, 테드와 팀. 가족만 아는 비밀을 안고 이번엔 팀의 딸 티나와 힘을 합친다. 비열한 악당의 음모를 무너뜨리기 위해.&quot;,
  },
  {
    id: 3,
    title: &quot;너의 이름은&quot;,
    director: &quot;신카이 마코토&quot;,
    category: &quot;일본 애니메이션&quot;,
    detail:
      &quot;도쿄의 잘생긴 남자로 살아볼 순 없을까? 따분한 시골 생활에 질려 도시를 동경하는 여고생. 어느 날, 그 소원이 실제로 이루어진다. 도쿄의 남고생과 이따금 몸이 뒤바뀌는 것. 꿈결 같은 둘의 인연은 또 다른 운명을 부르기 시작한다.&quot;,
  },
  {
    id: 4,
    title: &quot;아이 필 프리티&quot;,
    director: &quot;마크 실버스틴&quot;,
    category: &quot;미국 영화&quot;,
    detail:
      &quot;난 왜 예쁘지 않은 걸까. 외모가 불만인 그녀, 스피닝 수업에서 아찔한 사고를 당한다. 깨어나보니 확 뒤집힌 그녀의 인생! 커리어도, 연애도 이젠 핑크빛이다!&quot;,
  },
  {
    id: 5,
    title: &quot;트루먼쇼&quot;,
    director: &quot;피터 위어&quot;,
    category: &quot;미국 영화&quot;,
    detail:
      &quot;한 사람의 일거수일투족이 24시간 생방송 되는 &#39;트루먼 쇼&#39;의 주인공 트루먼 버뱅크. 엄청난 인기를 끌고 있는 이 프로그램의 주인공인 자신만 이 사실을 전혀 모르고 있다. 모든 것이 방송이라는 것이 밝혀지면 그는 과연 어떤 선택을 할까.&quot;,
  },
  {
    id: 6,
    title: &quot;아메리칸셰프&quot;,
    director: &quot;존 패브로&quot;,
    category: &quot;미국 영화&quot;,
    detail:
      &quot;창의력이 지글지글 끓어오르는 셰프. 똑같은 메뉴만 고집하는 주인과 지지고 볶은 후 허름한 푸드트럭을 차리면서 맛깔나는 좌충우돌 여정에 오른다. 배고플 땐 보지 말 것!&quot;,
  },
  {
    id: 7,
    title: &quot;인턴&quot;,
    director: &quot;낸시 마이어스&quot;,
    category: &quot;미국 영화&quot;,
    detail:
      &quot;뜨거운 열정으로 단기간에 회사를 키워낸 30대 열혈 여성 CEO. 사별과 은퇴를 겪고 공허한 일상을 보내다가 새내기로 입사한 70세 남성 인턴. 문제없을까, 이 어색한 조합.&quot;,
  },
  {
    id: 8,
    title: &quot;월요일이 사라졌다&quot;,
    director: &quot;토미 비르콜리&quot;,
    category: &quot;미국 영화&quot;,
    detail:
      &quot;우리는 하나다! 엄격한 산아제한 정책을 시행하는 미래. 정부의 감시를 피해, 일곱 쌍둥이가 한 사람처럼 산다. 들킨 걸까? 사라진 자매 하나를 찾아, 여섯이 힘을 합친다.&quot;,
  },
];

//movies 전체 데이터 조회
export function getMovies() {
  return movies;
}
</code></pre>
<h2 id="62-상세-페이지-컴포넌트-만들기">6.2 상세 페이지 컴포넌트 만들기</h2>
<p>Movies 컴포넌트 안에서 map함수를 이용해 data의 상세정보를 보여줄 것입니다. </p>
<p>이를 위해 pages폴더 안에 Movie 컴포넌트도 새로 생성해주세요
📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;

const Movie = () =&gt; {
  return &lt;div&gt;상세페이지입니다.&lt;/div&gt;;
};

export default Movie;
</code></pre>
<h2 id="63-url-파라미터-경로-지정">6.3 URL 파라미터 경로 지정</h2>
<p>URL 파라미터는 경로에 <code>:</code>을 사용하여 설정합니다.
📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./pages/Home&quot;;
import Movies from &quot;./pages/Movies&quot;;
import Menubar from &quot;./pages/Menubar&quot;;
import Movie from &quot;./pages/Movie&quot;;

const App = () =&gt; {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;/&quot; element={&lt;Menubar /&gt;}&gt;
        &lt;Route index element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/movies&quot; element={&lt;Movies /&gt;}&gt;
          &lt;Route path=&quot;:movieId&quot; element={&lt;Movie /&gt;} /&gt;
        &lt;/Route&gt;
      &lt;/Route&gt;
    &lt;/Routes&gt;
  );
};

export default App;
</code></pre>
<h2 id="64-영화-목록-리스트-만들기">6.4 영화 목록 리스트 만들기</h2>
<p>이제 Movies 컴포넌트에 movie_data를 불러오고, map함수를 이용해 영화 추천 리스트를 만들어보겠습니다.</p>
<p>📄<strong>pages/Movies.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Link, Outlet } from &quot;react-router-dom&quot;;
import { getMovies } from &quot;../movie_data&quot;;

const Movies = () =&gt; {
  const movies = getMovies();
  return (
    &lt;div&gt;
      &lt;h1&gt;넷플릭스 영화 추천 목록&lt;/h1&gt;
      &lt;div&gt;
        {movies.map((movie) =&gt; (
          &lt;Link
            to={`/movies/${movie.id}`}
            key={movie.id}
            style={{ display: &quot;block&quot; }}
          &gt;
            {movie.title}
          &lt;/Link&gt;
        ))}
      &lt;/div&gt;
      &lt;hr /&gt;
      &lt;Outlet /&gt;
    &lt;/div&gt;
  );
};

export default Movies;</code></pre>
<p>/movies/1 , /movies/2와 같은 형태로 movie_data의 id값이 URL파라미터 주소 값으로 들어가게 됩니다. map을 사용할 땐 반드시 key값을 지정해줘야 하기 때문에 movie_data의 id값을 넘겨주었습니다.</p>
<p>영화 목록이 잘 뜨나요?</p>
<h2 id="64-useparams">6.4 useParams</h2>
<p>이번엔 영화 목록을 클릭했을 때 상세 페이지가 목록 밑에 뜨도록 해보겠습니다.</p>
<p>URL 파라미터는 useParams라는 Hook을 사용해 객체 형태로 조회할 수 있습니다.
아래와 같이 Movie.js를 수정 후, Console창을 봅시다.</p>
<p>📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams } from &quot;react-router-dom&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  console.log(params);
  return &lt;div&gt;상세페이지입니다.&lt;/div&gt;;
};

export default Movie;

</code></pre>
<p>/movies/1 일 경우 1을
/movies/2 일 경우 2를 출력합니다.</p>
<p>즉 useParams로 URL 파라미터의 값이 조회되는 것을 알 수 있습니다.</p>
<p>조회된 파라미터 값과 movie_data의 id값이 같을 때 해당 id의 다른 정보들도 가져올 수 있도록 해봅시다.</p>
<p>먼저 movie_data에 id로 하나의 영화 정보만 가져오는 함수를 추가해줍니다.
📄<strong>src/movie_data.js</strong></p>
<pre><code class="language-javascript">...

export function getMovie(id) {
  return movies.find((movie) =&gt; movie.id === id);
}</code></pre>
<p>📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams } from &quot;react-router-dom&quot;;
import { getMovie } from &quot;../movie_data&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  console.log(params);
  const movie = getMovie(parseInt(params.movieId));
  console.log(movie);

  return &lt;div&gt;상세페이지입니다.&lt;/div&gt;;
};

export default Movie;
</code></pre>
<p>getMovie를 import 한 후, 조회된 파라미터 값을 인자로 넘겨줍니다. 
주의할 점은 파라미터 값이 문자열이기 때문에 반드시 숫자로 바꿔줘야 합니다.</p>
<p>console창을 보면 조회된 파라미터 값에 따라 movie 객체가 잘 출력되는 것을 볼 수 있습니다.</p>
<p>이를 이용해 상세 페이지를 만들어보겠습니다.</p>
<h2 id="65-영화-목록-클릭시-해당-영화-상세-페이지-띄우기">6.5 영화 목록 클릭시 해당 영화 상세 페이지 띄우기</h2>
<p>📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams } from &quot;react-router-dom&quot;;
import { getMovie } from &quot;../movie_data&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  console.log(params);
  const movie = getMovie(parseInt(params.movieId));
  console.log(movie);

  return (
    &lt;div&gt;
      &lt;h2&gt;{movie.title}&lt;/h2&gt;
      &lt;p&gt;감독 : {movie.director}&lt;/p&gt;
      &lt;p&gt;카테고리 : {movie.category}&lt;/p&gt;
    &lt;/div&gt;
  );
};

export default Movie;

</code></pre>
<p>영화의 제목, 감독, 카테고리가 화면에 잘 보여지나요?</p>
<h1 id="7-쿼리-스트링-사용하기">7. 쿼리 스트링 사용하기</h1>
<p>이번에는 쿼리 스트링을 사용하여 &#39;자세히&#39;버튼을 눌렀을 때 
<code>?detail=true</code> 이런 쿼리 스트링을 만들어 주어 영화의 간략한 줄거리가 나오도록 구현해보겠습니다.</p>
<p>쿼리 스트링은 URL파라미터와 달리 Route 컴포넌트를 별도로 설정하지 않아도 됩니다.</p>
<h2 id="71-uselocation">7.1 useLocation</h2>
<p>먼저, 페이지의 정보를 알기 위해 useLocation이라는 Hook을 사용해보겠습니다.
📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams, useLocation } from &quot;react-router-dom&quot;;
import { getMovie } from &quot;../movie_data&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  console.log(params);
  const movie = getMovie(parseInt(params.movieId));
  console.log(movie);

  //쿼리 스트링 사용하기
  const location = useLocation();
  console.log(location);

  return (
    &lt;div&gt;
      &lt;h2&gt;{movie.title}&lt;/h2&gt;
      &lt;p&gt;감독 : {movie.director}&lt;/p&gt;
      &lt;p&gt;카테고리 : {movie.category}&lt;/p&gt;
    &lt;/div&gt;
  );
};

export default Movie;</code></pre>
<p>console창을 보면 &#39;pathname&#39;, &#39;search&#39;, &#39;hash&#39;, &#39;state&#39;, &#39;key&#39;값들이 출력되고 있음을 알 수 있습니다. </p>
<p>이 상태에서 주소 창에
<a href="http://localhost:3000/movies/1?detail=true">http://localhost:3000/movies/1?detail=true</a>
처럼 입력한 후 콘솔창에 변화를 지켜보세요!</p>
<p>&#39;search&#39;에 ?를 포함한 쿼리스트링이 값으로 들어가 있음을 알 수 있습니다.</p>
<p>이렇게 쿼리스트링은 useLocation의 search값을 통해 조회가 가능합니다.</p>
<h2 id="72-usesearchparams">7.2 useSearchParams</h2>
<p>이번에는 조회한 쿼리스트링을 파싱하여 자세히 버튼을 눌렀을 때는 detail 값에 true를 한 번 더 누르면 false 값을 주도록 하겠습니다.</p>
<p>쿼리스트링을 파싱할 때는 useSearchParams라는 Hooke을 사용합니다.</p>
<p>📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams, useLocation, useSearchParams } from &quot;react-router-dom&quot;;
import { getMovie } from &quot;../movie_data&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  console.log(params);
  const movie = getMovie(parseInt(params.movieId));
  console.log(movie);

  //쿼리 스트링 사용하기
  const location = useLocation();
  console.log(location);

  const [searchParams, setSearchParams] = useSearchParams();
  console.log(searchParams.get(&quot;detail&quot;));

  return (
    &lt;div&gt;
      &lt;h2&gt;{movie.title}&lt;/h2&gt;
      &lt;p&gt;감독 : {movie.director}&lt;/p&gt;
      &lt;p&gt;카테고리 : {movie.category}&lt;/p&gt;
    &lt;/div&gt;
  );
};

export default Movie;
</code></pre>
<p>useSearchParams의 get은 쿼리파라미터를 조회하고, set메서드는 특정 쿼리파라미터를 업데이트 할 수 있습니다.</p>
<p>아직 주소창에 
<a href="http://localhost:3000/movies/1?detail=true">http://localhost:3000/movies/1?detail=true</a>
이 입력되어 있나요?</p>
<p>현재 console창에 &quot;detail&quot; 쿼리 파라미터의 값을 반환하도록 하였더니 &#39;true&#39;라는 값이 잘 출력되는 모습을 볼 수 있습니다.</p>
<h2 id="72-자세히-버튼-만들고-이벤트-생성하기">7.2 자세히 버튼 만들고 이벤트 생성하기</h2>
<p>이제 useSearchParams와 useLocation을 이용해 자세히 보기 버튼을 만들고, 클릭 이벤트 발생 시 &quot;detail&quot;쿼리 파라미터의 값이 변경되도록 만들어보겠습니다.</p>
<p>📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams, useLocation, useSearchParams } from &quot;react-router-dom&quot;;
import { getMovie } from &quot;../movie_data&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  //console.log(params);
  const movie = getMovie(parseInt(params.movieId));
  //console.log(movie);

  //쿼리 스트링 사용하기
  const location = useLocation();
  //console.log(location);

  const [searchParams, setSearchParams] = useSearchParams();
  const detail = searchParams.get(&quot;detail&quot;);

  const handleClick = () =&gt; {
    setSearchParams({ detail: detail === &quot;true&quot; ? false : true });
    console.log(detail);
  };

  return (
    &lt;div&gt;
      &lt;h2&gt;{movie.title}&lt;/h2&gt;
      &lt;p&gt;감독 : {movie.director}&lt;/p&gt;
      &lt;p&gt;카테고리 : {movie.category}&lt;/p&gt;
      &lt;button onClick={handleClick} type=&quot;button&quot;&gt;
        자세히
      &lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Movie;
</code></pre>
<p>버튼을 누를 때마다 detail의 값이 잘 바뀌나요?</p>
<p>이제 삼항 연산자를 이용해 detail 값이 true 면 보이고 아니면 보이지 않게 하겠습니다. 
주의할 점은 detail안에 저장된 파라미터의 true값은 문자열 이기 때문에 비교시 꼭 <code>&quot; &quot;</code>로 묶어줘야 합니다.</p>
<p>📄<strong>pages/Movie.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { useParams, useLocation, useSearchParams } from &quot;react-router-dom&quot;;
import { getMovie } from &quot;../movie_data&quot;;

const Movie = () =&gt; {
  //URL 파라미터 사용하기
  const params = useParams();
  //console.log(params);
  const movie = getMovie(parseInt(params.movieId));
  //console.log(movie);

  //쿼리 스트링 사용하기
  const location = useLocation();
  //console.log(location);

  const [searchParams, setSearchParams] = useSearchParams();
  const detail = searchParams.get(&quot;detail&quot;);

  const handleClick = () =&gt; {
    setSearchParams({ detail: detail === &quot;true&quot; ? false : true });
    console.log(detail);
  };

  return (
    &lt;div&gt;
      &lt;h2&gt;{movie.title}&lt;/h2&gt;
      &lt;p&gt;감독 : {movie.director}&lt;/p&gt;
      &lt;p&gt;카테고리 : {movie.category}&lt;/p&gt;
      &lt;button onClick={handleClick} type=&quot;button&quot;&gt;
        자세히
      &lt;/button&gt;
      {detail === &quot;true&quot; ? &lt;p&gt;{movie.detail}&lt;/p&gt; : &quot; &quot;}
    &lt;/div&gt;
  );
};

export default Movie;
</code></pre>
<h1 id="8-리액트-라우터-부가기능-사용하기">8. 리액트 라우터 부가기능 사용하기</h1>
<h2 id="81-notfound-페이지">8.1 NotFound 페이지</h2>
<p>Route로 지정해 주지 않은 경로로 들어갔을 때 찾을 수 없는 페이지 임을 사용자에게 알려주는 처리가 필요합니다.</p>
<p>App.js를 다음과 같이 수정해볼께요
📄<strong>App.js</strong></p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./pages/Home&quot;;
import Movies from &quot;./pages/Movies&quot;;
import Menubar from &quot;./pages/Menubar&quot;;
import Movie from &quot;./pages/Movie&quot;;

const App = () =&gt; {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;/&quot; element={&lt;Menubar /&gt;}&gt;
        &lt;Route index element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/movies&quot; element={&lt;Movies /&gt;}&gt;
          &lt;Route path=&quot;:movieId&quot; element={&lt;Movie /&gt;} /&gt;
        &lt;/Route&gt;
        &lt;Route path=&quot;*&quot; element={&lt;div&gt;There&#39;s nothing here!&lt;/div&gt;} /&gt;
      &lt;/Route&gt;
    &lt;/Routes&gt;
  );
};

export default App;</code></pre>
<p><a href="http://localhost:3000/Board">http://localhost:3000/Board</a>
이렇게 입력해보세요! 존재하지 않은 페이지라고 잘 뜨나요?</p>
<h2 id="82-navigate-컴포넌트">8.2 Navigate 컴포넌트</h2>
<p>페이지를 이동할 때는 Link 컴포넌트 이외에 또 다른 방법이 있습니다.
바로 Navigate 컴포넌트를 사용하는 방식입니다.</p>
<p>하단에 홈으로 돌아가는 버튼을 만들어볼께요</p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { Link, Outlet, useNavigate } from &quot;react-router-dom&quot;;

const Menubar = () =&gt; {
  //Navigate 사용하기
  const navigate = useNavigate();
  const goHome = () =&gt; {
    navigate(&quot;/&quot;);
  };
  return (
    &lt;div&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/&quot;&gt;Home&lt;/Link&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;Link to=&quot;/movies&quot;&gt;Movies&lt;/Link&gt;
        &lt;/li&gt;
      &lt;/ul&gt;

      &lt;Outlet /&gt;

      &lt;button onClick={goHome}&gt;홈으로 돌아가기&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Menubar;
</code></pre>
<h2 id="83-navlink">8.3 NavLink</h2>
<p>Link 대신 NavLink 컴포넌트를 사용하면 링크에서 사용하는 경로가 현재 라우트의 경로와 일치하는 경우 특정 CSS를 적용할 수 있습니다.</p>
<p>영화 목록 리스트 중 선택되어져 있는 리스트에 스타일을 적용해보도록 할께요.</p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
import { NavLink, Link, Outlet } from &quot;react-router-dom&quot;;
import { getMovies } from &quot;../movie_data&quot;;

const Movies = () =&gt; {
  const movies = getMovies();
  return (
    &lt;div&gt;
      &lt;h1&gt;넷플릭스 영화 추천 목록&lt;/h1&gt;
      &lt;div&gt;
        {movies.map((movie) =&gt; (
          &lt;NavLink
            to={`/movies/${movie.id}`}
            key={movie.id}
            style={({ isActive }) =&gt; {
              return {
                textDecoration: isActive ? &quot;underline&quot; : &quot;&quot;,
                color: isActive ? &quot;#FF9E1B&quot; : &quot;&quot;,
              };
            }}
          &gt;
            &lt;p&gt;{movie.title}&lt;/p&gt;
          &lt;/NavLink&gt;
        ))}
      &lt;/div&gt;
      &lt;hr /&gt;
      &lt;Outlet /&gt;
    &lt;/div&gt;
  );
};

export default Movies;
</code></pre>
<p>선택된 영화 제목만 주황색으로 바뀌는 것을 확인하였나요?</p>
<p>여기까지 React Router를 활용한 프로젝트 만들기 따라오시느라 고생많으셨습니다!</p>
<p>CSS가 적용된 버전은 아래 github를 참고해주세요!
<a href="https://github.com/Chanran33/practice_router">https://github.com/Chanran33/practice_router</a></p>
<hr>

<p>** 참고자료 **
React Router v6 튜토리얼 : <a href="https://velog.io/@velopert/react-router-v6-tutorial#42-%EC%BF%BC%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A7%81">https://velog.io/@velopert/react-router-v6-tutorial#42-%EC%BF%BC%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A7%81</a>
React Router Tutorial : <a href="https://reactrouter.com/docs/en/v6/getting-started/tutorial#tutorial">https://reactrouter.com/docs/en/v6/getting-started/tutorial#tutorial</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MPA와 SPA]]></title>
            <link>https://velog.io/@sparkling0_0/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%BD%94%EC%8A%A4React-Routerv6-%EC%97%B0%EC%8A%B5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@sparkling0_0/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%BD%94%EC%8A%A4React-Routerv6-%EC%97%B0%EC%8A%B5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 21 Apr 2022 20:18:52 GMT</pubDate>
            <description><![CDATA[<h1 id="--mpamultiple-page-application">- MPA(Multiple Page Application)</h1>
<p><img src="https://velog.velcdn.com/images/sparkling0_0/post/60795fe0-b321-4b17-960a-7ddbde15bee3/image.png" alt=""></p>
<ul>
<li>여러 개의 페이지로 구성된 웹 애플리케이션</li>
<li>사용자가 새로운 페이지를 요청할 때마다 서버에서 미리 준비한 화면을 보여준다.</li>
</ul>
<h2 id="mpa의-단점">MPA의 단점</h2>
<ul>
<li>페이지를 이동하거나 새로고침할 때, 전체 페이지를 다시 렌더링 하기 때문에 사용자의 인터페이스에서 사용하고 있던 <strong>상태를 유지하기도</strong> 번거롭고, 바뀌지 않는 부분까지 새로 불러와 보여 주기 때문에 <strong>불필요한 로딩</strong>이 발생되게 된다.</li>
</ul>
<h1 id="--spasingle-page-application">- SPA(Single Page Application)</h1>
<p><img src="https://velog.velcdn.com/images/sparkling0_0/post/849c0ce8-f771-483a-ae62-cc7294296ebd/image.png" alt=""></p>
<ul>
<li>한 개의 페이지로 구성된 웹 애플리케이션 </li>
<li>첫 요청시에 딱 한 페이지만 불러온 후, 페이지 이동 시 기존 페이지의 내부를 수정해서 화면을 보여준다.</li>
<li>리액트가 사용하는 방식이다.</li>
</ul>
<blockquote>
<p><strong>어떻게 한 개의 페이지로 여러 화면을 보여줄 수 있을까❓</strong>
👉 SPA는 _서버에서 사용자에게 제공하는 페이지는 한 개_이지만, 해당 페이지에서 로딩된 자바스크립트와 현재 사용자 브라우저의 주소 상태에 따라 다양환 화면을 보여 줄 수 있다.</p>
</blockquote>
<p>이렇게 다른 주소에 다른 화면을 보여주는 것을 <strong>라우팅</strong>이라 한다.</p>
<hr>

<p><strong>참고자료</strong></p>
<ul>
<li>spa와 mpa : <a href="https://hanamon.kr/spa-mpa-ssr-csr-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%9C%BB%EC%A0%95%EB%A6%AC/">https://hanamon.kr/spa-mpa-ssr-csr-장단점-뜻정리/</a></li>
<li>리액트를 다루는 기술(김민준 지음) / 길벗</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React]리액트 라우터 URL 매개변수 읽기]]></title>
            <link>https://velog.io/@sparkling0_0/React%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9A%B0%ED%84%B0-URL-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%BD%EA%B8%B0</link>
            <guid>https://velog.io/@sparkling0_0/React%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9A%B0%ED%84%B0-URL-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%BD%EA%B8%B0</guid>
            <pubDate>Wed, 23 Mar 2022 21:18:24 GMT</pubDate>
            <description><![CDATA[<p>게시판 목록을 만들고, detail View를 만들던 중</p>
<pre><code>&lt;Link to={`/study_main/${study.id}`} /&gt;</code></pre><p>형식으로 넘긴 페이지에서 끝의 매개변수 값을 읽어 
axios url에 넘기고 싶었다.</p>
<p>처음엔 state와 props를 이용할 생각이었으나 계속해서 NULL값이 나왔다.</p>
<p>React 라우터 공식문서를 읽어보니 라우터의 useParams함수를 이용해 쉽게 매개변수를 읽어올 수 있었다.</p>
<p>라우터가 다음과 같이 구성되어 있을 경우</p>
<pre><code>&lt;Route path=&quot;/study_main&quot; element={&lt;StudyMain /&gt;}&gt;
    &lt;Route index element={&lt;StudyList /&gt;} /&gt;
    &lt;Route path=&quot;:studyId&quot; element={&lt;Study /&gt;} /&gt;
&lt;/Route&gt;</code></pre><p><code>&lt;StudyList&gt;</code> 컴포넌트에서 게시판 글의 목록을 불러오고, 하나의 게시판 글을 읽으면 detail 페이지로 넘어가기 위하여</p>
<pre><code>&lt;Link to={`/study_main/${study.id}`} /&gt;</code></pre><p><code>&lt;Link&gt;</code>태그로 묶어주었다.</p>
<p>넘어간 <code>&lt;Study&gt;</code> 페이지에서</p>
<pre><code class="language-js">import React, { useEffect } from &#39;react&#39;;
import axios from &#39;axios&#39;;
import { useParams } from &#39;react-router-dom&#39;;

const Study = () =&gt; {
  const params = useParams();

  useEffect(() =&gt; {
    const id = params.studyId;
    axios
      .get(`http://localhost:3001/study/studies/${id}`)
      .then((res) =&gt; {
        console.log(res.data);
      })
      .catch((error) =&gt; console.log(&#39;Network Error : &#39;, error));
  });
  return &lt;div&gt;&lt;/div&gt;;
};
</code></pre>
<p>useParams.params이름 으로 쉽게 넘겨받은 매개변수 값을 읽어올 수 있었다!</p>
<p>GOOD~!</p>
<p>※ 참고 React 라우터 공식문서
<a href="https://reactrouter.com/docs/en/v6/getting-started/tutorial#reading-url-params">https://reactrouter.com/docs/en/v6/getting-started/tutorial#reading-url-params</a></p>
]]></description>
        </item>
    </channel>
</rss>