코딩앙마님의 강의를 보고 정리한 글입니다.
https://www.youtube.com/watch?v=vI-XtN_Zdfg&list=PLZKTXPmaJk8J_fHAzPLH8CJ_HO_M33e7-&index=10
본격적인 페이지 만들기
이제 페이지를 만들기 위해 불필요한 파일들을 다 삭제해준 후 먼저 토익 영단어 앱을 만들기 위해 먼저 헤더를 만들어준다.
export default function Header() {
return (<div className="header">
<h1>
<a>토익 영단어(고급)</a>
</h1>
<div className="menu">
<a href="#x" className="link">
단어 추가
</a>
<a href="#x" className="link">
Day 추가
</a>
</div>
</div>
);
}
그다음 App 컴포넌트에서 연결해주면
이렇게 뜬다. 이제 이 밑에 day 별로 영단어를 확인할 수 있도록 해야 하는데 그러기 위해선 day별 영단어를 json으로 더미 데이터를 구현해야 한다.
이런 식으로! 데이터는 코딩앙마님의 깃헙에서 복사했다.
이제 이 데이터를 메인 화면에 day별로 목록으로 띄워보자.
import dummy from "../db/data.json";
export default function DayList(){
return <ul className="list_day">
{dummy.days.map(day => (
<li key={day.id}>
Day {day.day}
</li>
))}
<li></li>
</ul>;
}
먼저 json 파일을 dummy라는 이름으로 불러온다.
그다음 ul 태그를 만들어서 그 안에 dummy의 day가 li의 형태로 뜨게 해 주면 되는데 이것은 for문 혹은 map을 사용해주면 된다. 그래서 map을 사용해서 데이터의 day 값을 불러와 출력되도록 하였다.
key 값의 경우 리액트에서 관리하기 위해 요구하는 것이기 때문에 데이터의 id 값을 넣어주면 된다.
이제 특정 날짜를 클릭해서 들어갔을 때 단어들이 나오도록 하는 Day 컴포넌트를 만들어 보자.
import dummy from "../db/data.json";
export default function Day(){
//dummy.words를 사용
return(
<>
<table>
<tbody>
{dummy.words.map(word => (
<tr>
<td>{word.eng}</td>
<td>{word.kor}</td>
</tr>
))}
</tbody>
</table>
</>
);
}
이번에도 더미 데이터를 사용해서 컴포넌트를 만들었다. 영어와 한글 뜻이 표 형태로 나올 수 있도록 table 태그를 사용하였다.
하지만 2가지의 문제점이 있다.
첫 번째는 모든 단어가 다 나오고 있다는 것이다. Day 1을 클릭하면 Day 1에 해당하는 단어들만 보이도록 해야 한다.
두 번째는 단어들이 저기에 바로 나오면 안 되고 Day를 클릭했을 때 새로운 페이지로 가서 해당하는 단어들이 나오도록 해야 한다.
리액트 라우터를 사용해서 페이지를 이동해보자.
▷리액트 라우터란?
사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것. 즉, URL에 따라 페이지에 렌더링 해주는 라이브러리이다.
npm install react-router-dom
을 통해 설치 후 사용이 가능하다.
리액트 라우터를 설치했으면 이제 App.js에 연결해주면 된다.
(강의는 v5이고 강의를 보고 있는 지금은 v6이다. 따라서 v6에 맞춰서 코드를 작성해야 한다.)
import {BrowserRouter, Route, Routes} from 'react-router-dom';
function App() {
return (
<div className="App">
<BrowserRouter>
<Header/>
<Routes>
<Route path="/" element={<DayList/>}/>
<Route path="/day" element={<Day/>}/>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
import로 연결해주고 전체를 BrowerRouter로 감싼다. Header는 모든 화면에서 공통적으로 나타날 것이기 때문에 그대로 두고 페이지가 이동하게 될 DayList 와 Day를 Routes로 감싸고 각각 Route로 url을 지정한다.
즉, BrowerRouter는 리액트 라우터를 시작하는 코드이고, Routes 내부는 url에 따라 페이지가 이동되고 외부는 모든 페이지에서 공통적으로 보이는 부분인 것이다.
path="/"는 가장 처음 화면을 보여준다. 그리고 /day 가 되면 Day 컴포넌트를 보여줄 것이다.
이제 DayList에 링크를 연결해주자!
html에서는 a태그와 href 속성을 사용하지만 리액트 라우터에서는 Link 태그와 to 속성을 사용한다.
import dummy from "../db/data.json";
import { Link } from "react-router-dom";
export default function DayList(){
return <ul className="list_day">
{dummy.days.map(day => (
<li key={day.id}>
<Link to={`/day/${day.day}`}>Day {day.day}</Link>
</li>
))}
<li></li>
</ul>;
}
DayList에서 Link 태그를 이용해서 해당하는 Day로 페이지를 이동하도록 한다.
to={`/day/${day.day}`}를 통해 데이터를 통해 받는 day 값으로 주소를 이동하게 된다. day/1, day/2... 이렇게!
그러면 그렇게 받아온 url로 어떻게 이동할 수 있을까?
<Route path="/day/:day" element={<Day/>}/>
콜론을 사용하면 된다. :day를 사용하면 day라는 변수 안에 위에서 제공한 day.day값이 들어오게 되는 것.
이제 이 url에 따라 출력하는 화면을 바꿔보자.
url에 포함된 값을 얻을 때는 useParams를 사용한다.
import { useParams } from "react-router-dom";
export default function Day(){
//dummy.words를 사용
const day = 1;
const wordList = dummy.words.filter(word => word.day === day);
const a = useParams();
console.log(a);
useParams가 어떤 값을 가지고 있는지 콘솔에 출력해보면
url의 day 값을 받아오는 것을 볼 수 있다.
만약 주소를 /day/80으로 찍으면
이렇게 80이 들어온다.
즉 아까 콜론으로 받았던 day 변수가 반환되는 것.
그러면 이 값을 사용해서
const a = useParams();
const day = a.day;
클릭되는 콘텐츠로 day의 값을 변경할 수 있다.
이제 이렇게! 해당하는 Day의 값으로 이동할 수 있게 되었다.
하지만 밑에 단어 목록은 나타나지 않고 있는데 그 이유는 이렇게 받아온 값은 문자열이고 filter에서 비교하는 값은 숫자이기 때문에 성립하지 않는 것이다.
Day 컴포넌트에서
const wordList = dummy.words.filter(word => word.day === Number(day));
숫자끼리 비교할 수 있도록 하면?
이렇게 Day에 해당하는 단어가 나타난다.
마지막으로 설정되지 않은 주소를 입력했을 때 홈으로 돌아갈 수 있도록 하는 EmptyPage 컴포넌트를 만들어보자.
import { Link } from "react-router-dom";
export default function EmptyPage(){
return(
<>
<h2>잘못된 접근입니다.</h2>
<Link to="/">돌아가기</Link>
</>
)
}
import EmptyPage from "./component/EmptyPage";
function App() {
return (
<div className="App">
<BrowserRouter>
<Header/>
<Routes>
<Route path="/" element={<DayList/>}/>
<Route path="/day/:day" element={<Day/>}/>
<Route path="*" element={<EmptyPage/>}/>
</Routes>
</BrowserRouter>
</div>
);
}
이렇게 다른 주소에 해당하지 않을 때 EmptyPage를 보여주도록 하면 완료!
'개발 공부 > React' 카테고리의 다른 글
React #10 [PUT, DELETE] (0) | 2022.09.12 |
---|---|
React #9 [json-server, REST API, custom hook] (0) | 2022.08.27 |
React #7 [컴포넌트, CSS, 이벤트, state, props] (0) | 2022.08.23 |
React #6 [update, delete] (0) | 2022.08.09 |
React #5 [props와 state, create, push와 concat] (0) | 2022.07.16 |