드디어 마지막 주차이다.
이번에는 API 연동과 React Router에 대해 알아보고자 한다.
4-1. API 연동의 기본
새로운 프로젝트를 만들어 준다.
그리고 axios 라는 라이브러리를 설치한다. (API 호출 위함)
axios는 브라우저와 Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이다. 모든 브라우저를 지원한다.
axios를 이용해서 GET, PUT, POST, DELETE 등의 메서드로 API요청을 할 수 있다.
GET : 데이터 조회
POST : 데이터 등록
PUT : 데이터 수정
DELETE : 데이터 제거
axios는 아래처럼 불러오고, 사용한다.
import axios from 'axios';
axios.get('/users/1');
2번째 줄에서 axios 뒤에는 메서드 이름을 소문자 (get, post, put, delete)로 넣는다.
axios.post('/users',{
username : 'test',
name : 'Jeong'
});
axios.post로 데이터 등록 시 두 번째 파라미터에 등록하고자 하는 정보를 넣는다.
이번 API 연동 실습은 JSONPlaceholder 에 있는 연습용 API를 쓸 예정이다.
주소는 다음과 같다.
https://jsonplaceholder.typicode.com/users
useState와 useEffect로 데이터 로딩하기
useState를 사용해서 요청 상태를 관리하고, useEffect를 사용해서 컴포넌트가 렌더링되는 시점에 요청을 시작해 보자.
요청에 대한 상태 관리시 3가지를 관리해줘야 한다.
1. 요청의 결과
2. 로딩 상태
3. 에러
아래와 같이 Users.js코드를 작성해 준다.
useEffect 의 첫 번째 파라이터로 등록하는 함수에는 async를 쓸 수 없기 때문에 함수 내부에서 async를 쓰는 새로운 함수를 선언해 주어야 한다.
로딩 상태 활성화시 -> 로딩중.. 문구 출력
user 값이 없을 때 -> null 을 출력
맨 마지막 -> users 배열을 렌더링
App.js를 수정해 User 컴포넌트를 렌더링 해준다.
그리고 yarn start를 누르면....
아주 잘 불러왔다.
에러 발생 확인하기
주소를 이상하게 바꿔 에러가 발생하는지 알아보자.
주소가 이상하게 바뀌자마자
에러를 띄운다.
ㅇㅖ....
버튼을 눌러서 API 재요청하기
이번엔 버튼을 눌렀을 때 API 를 재요청하도록 해보자.
fetchUsers함수를 밖으로 꺼내고, 버튼을 만들어서 함수를 연결해준다.
실행해 보면..
못 보던 버튼이 있다. 이 버튼을 누르면 다시 불러온다.
React Router v6 튜토리얼
1. 라우팅이란?
'사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것'이다.
예를 들어, 블로그를 만든다고 가정한다면, 크게 아래 페이지들이 필요하다.
글쓰기 페이지
포스트 목록 페이지
포스트 읽기 페이지
위와 같이 여러 페이지로 구성이 되어 있을때, 페이지별로 컴포넌트를 분리해 가며 프로젝트를 관리하기 위해 필요한 것이
라우팅 시스템이다.
리액트에서는 크게 두가지 선택지를 활용하여 라우팅 시스템을 구축할 수 있다.
React Router : 라우팅 라이브러리 중 가장 오래되었고, 제일 많이 쓴다. 컴포넌트 기반으로 라우팅 시스템 설정
Next.js : 리액트의 프레임워크, 다양한 기능 제공, Next.js의 라우팅 시스템은 파일 기반으로 작동. 위 선택지의 대안으로 활용됨
리액트 라우터를 쓰면 손쉽게 Single Page Application을 만들 수 있다.
2. Single Page Application이란?
말 그대로 한 개의 페이지로 이루어진 애플리케이션이다.
엥? 방금전 여러 페이지로 구성되어 있는 걸 편히 관리하기 위해 라우팅을 쓴다고 했는데...?
먼저 멀티 페이지 애플리케이션을 알아보자. 멀티 페이지 애플리케이션은 사용자가 다른 페이지를 이동할 때 마다
새로운 html을 받아오고,
서버에서 리소스를 전달받는다.
사용자 인터렉션이 많은 페이지는 페이지 이동 시 불러올 자원이 많아 이 방법에 적합하지 않다.
그래서 리액트를 써서 사용자와의 인터랙션 발생 시 필요한 부분만 자바스크립트를 사용하여 업데이트하는 방식을 이용한다.
html은 단 한번만 받아온다는 것이 핵심이다. 그 이후에 필요 데이터만 받아와서 업데이트 해주는 것이 싱글 페이지 애플리케이션이다.
즉, 기술적으로는 한 페이지 이지만, 사용자 입장에서는 여러 페이지가 존재하는 것처럼 느낄 수 있다.
3. 리액트 라우터 적용 및 기본 사용법
3.1 프로젝트 생성 및 라이브러리 설치
$ yarn create react-app router-tutorial
그 뒤 아래 명령어를 입력하여 react router를 설치해준다.
$ cd router-tutorial
$ yarn add react-router-dom
3.2 프로젝트에 라우터 적용
src/index.js파일에서 react-router-dom에 내장된 BrowserRouter라는 컴포넌트를 이용해 감싸면 된다.
index.js를 아래와 같이 수정해주자.
3.3 페이지 컴포넌트 만들기
src/pages/Home.js | src/pages/About.js |
위처럼 코드를 작성해 준다.
3.4 Route 컴포넌트로 특정 경로에 원하는 컴포넌트 보여주기
사용자의 브라우저 주소 경로에 따라 원하는 컴포넌트를 보여주기 위해 Route라는 컴포넌트를 쓴다.
Route 컴포넌트는 다음과 같이 쓴다.
<Route path = "주소규칙" element = {보여 줄 컴포넌트 JSX} />
Route 컴포넌트는 Routes 컴포넌트 내부에서 써야 한다.
즉, Route 컴포넌트는 Routes 컴포넌트에 감싸져 있어야 한다.
yarn start를 입력하면...
/ | /About |
위처럼 잘 뜬다.
3.5 Link 컴포넌트를 사용하여 다른 페이지로 이동하는 링크 보여주기
Link 컴포넌트를 사용해서 다른 페이지로 이동하는 링크를 보여주자.
원래는 a태그를 사용하는데, a태그를 쓰면 페이지를 새로 불러오기 때문에 리액트에서는 바로 이걸 쓰면 안된다.
Link 컴포넌트도 a 태그를 쓰긴 하는데, 페이지를 새로 불러오는 걸 막고, History API를 통해 브라우저 주소의 경로만 바꿔준다.
Link 컴포넌트는 아래와 같이 쓴다.
<Link to="경로">링크 이름</Link>
아래와 같이 Home.js를 수정하여 About로 이동하는 코드를 만들어보자
소개 버튼을 누르면 About 페이지로 이동한다.
4. URL 파라미터와 쿼리스트링
페이지 주소 정의 시 유동적인 값을 쓸 때가 있다.
URL 파라미터 예시 : /profile/velopert
쿼리스트링 예시 : /articles?**page=1&keyword=react
URL 파라미터는 주소의 경로에 유동적인 값을 넣는 것이고,
쿼리 스트링은 주소의 뒷부분에 ? 문자열 이후에 key = value 로 값을 정의하며 &로 구분을 하는 형태이다.
URL 파라미터는 주로 ID 또는 이름을 사용해 특정 데이터 조회 시,
쿼리스트링은 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션 전달 시 사용한다.
4.1 URL 파라미터
URL 파라미터를 사용해보자.
매우 복잡해 보인다....
- URL 파라미터는 useParams라는 Hook을 사용해 객체 형태로 조회 가능하다.
- URL 파라미터의 이름은 라우트 설정 시 Route 컴포넌트의 path props를 통해 설정한다.
- data객체에 예시 프로필 정보들을 키-값 형태로 담아뒀다.
- profile 컴포넌트에서는 data의 username을 조회해 이를 profile에 담은 뒤, 삼항 연산자를 사용해 프로필을 조회하고,
없을 시 나타나는 화면을 각각 지정해준다.
- 즉, {profile ? () : () } 이런 구조이다.
App.js에서 라우트를 새롭게 지정해 준다.
URL 파라미터는 /profiles/:username과 같이 경로에 :를 사용해서 설정한다.
URL 파라미터가 여러개라면 /profiles/:username/:field와 같은 형태로도 설정 가능하다.
링크가 여러개라, ul태그를 이용하여 리스트 형태로 보여준다.
URL 파라미터에 따라 결과물이 잘 보여진다.
4.2 쿼리스트링
쿼리스트링 사용시 URL파라미터와 달리 Route 컴포넌트를 사용할 때 별도로 설정할 건 없다.
useLocation이라는 Hook을 썼다. 이건 location이라는 객체를 반환하며, 현재 사용자가 보고 있는 페이지의 정보를 지니고 있다.
이 객체의 반환값들은 다음과 같다.
- pathname : 현재 주소의 경로 (쿼리스트링 제외)
- search : 맨 앞의 ? 문자 포함한 쿼리스트링 값
- hash : 주소의 # 문자열 뒤의 값 (주로 구형 브라우저에서 클라이언트 라우팅 사용 시 쓰는 해시 라우터에서 씀)
- state : 페이지로 이동할 때 임의로 넣을 수 있는 상태 값
- key : location 객체의 고유 값, 초기에는 default 이며 페이지 변경 시 고유값 생성됨
직접 주소창에
http://localhost:3000/about?detail=true&mode=1
를 입력해 보자.
실제 쿼리스트링 값이 출력된다.
리액트 라우터에서는 useSearchParams라는 Hook을 통해 쿼리스트링을 쉽게 다룰 수 있게 되었다.
useSearchParams를 사용해서 쿼리스트링을 파싱한 예시이다.
- useSearchParams는 배열 타입의 값을 반환, 첫 번째 원소는 쿼리파라미터를 조회, 수정하는 메서드들이 담긴 객체 반환
- get 메서드를 통해 조회를, set 메서드를 통해 업데이트 할 수 있다.
- 조회 시 쿼리파라미터 미존재 시 null 로 조회
- 두 번째 원소는 쿼리파라미터를 객체형태로 업데이트를 할 수 있는 함수 반환
- 주의점 : 쿼리파라미터 조회 시 값은 무조건 문자열 타입!
예를 들어, true, false 값을 넣게 되면 'true' 'false'등으로 입력하고, 숫자는 parseInt를 써야 한다.
5. 중첩된 라우트
src/pages/Articles.js | src/pages/Article.js |
위와 같이 코드를 작성해 준다. 이제 App 컴포넌트에서 라우트를 설정한다.
이 역시 : 문자열을 id앞에 써준다.
이 역시 리스트 안에 Link컴포넌트를 이용해서 연결해 준다.
만약 게시글 목록 페이지에서 게시글을 열었을때, 다시 게시글 하단에 목록을 보여줘야 한다면?
중첩된 라우트 형태로 구현할 수 있다.
우선 Article컴포넌트를 Articles컴포넌트 안에 중첩시켜 준다.
그리고 Articles컴포넌트에서 Outlet이라는 컴포넌트를 써야 한다.
이 컴포넌트는 Route의 children으로 들어가는 JSX 엘리먼트들을 보여주는 역할을 한다.
저 <Outlet/>이 중첩된 라우트를 보여지게 한다. ("/articles/1"이 맞다.... 수정했다.)
게시글 하단에 게시글 목록이 잘 나타난다.
5.1 공통 레이아웃 컴포넌트
중첩 라우터와 Outlet은 페이지끼리 공통적으로 보여줘야 하는 레이아웃이 있을 때도 유용히 쓸 수 있다.
Home, About, Profile에서 상단 헤더를 보여줘야 할 때를 생각해 보자.
보통 Header컴포넌트를 만들고 이를 재사용하는 방법을 생각한다. (나도 이렇게 생각함)
하지만, 중첩 라우트와 Outlet을 활용할 수도 있다. 이는 컴포넌트를 한 번만 써도 된다.
각 페이지 컴포넌트가 보여져야 하는 부분에 Outlet을 썼다.
이제 3개의 Route 컴포넌트들을 Layout안에 넣어준다.
이제 페이지를 이동할 때 마다 Header가 보인다.
5.2 index props
Route에는 index라는 props가 있다. 이는 path = "/" 와 동일하다.
이 index prop은 상위 라우트의 경로와 일치하지만, 그 이후에 경로가 주어지지 않았을 때 보여지는 라우트를 설정할 때 사용한다.
즉, 우리가 바꾼 index부분은 원래 path = "/"였고, 상위 라우트인 path = "/"와 일치한다. 또한, 그 이후에 경로가 주어지지 않았다.
그래서 index로 대체할 수 있다.
6. 리액트 라우터 부가기능
6.1 useNavigate
useNavigate는 Link 컴포넌트를 쓰지 않고 다른 페이지로 이동을 해야 할 때 쓴다.
위와 같이 수정해 준다.
뒤로가기를 누르면, navigate(-1)이 실행되며, 뒤로 한 번 간다. navigate(1)을 하면, 앞으로 한번 간다.
다른 페이지로 이동 시 replace라는 옵션이 있는데, 이를 쓰면 페이지 이동 시 현재 페이지를 기록에 남기지 않는다.
articles로 가면, 이전 페이지의 기록이 남지 않는다.
그래서 Home - About - Articles로 간 뒤에, 뒤로가기를 누르면 About이 아니라 Home으로 간다.
6.2 NavLink
NavLink 컴포넌트는 링크에서 쓰는 경로가 현재 라우트의 경로와 일치하는 경우, 특정 스타일 또는 CSS 스타일을 적용하는 컴포넌트이다.
이 컴포넌트를 사용할 때 style또는 className을 설정할 때 { isActive:boolean } 을 파라미터로 전달받는 함수 타입의 값을 전달한다.
<NavLink
style = {({isActive}) => isActive ? activeStyle : undefined}
/>
<NavLink
className = {({isActive}) => isActive ? 'active' : undefined}
/>
예시!!
위 코드처럼 바꿔준다. 조금 복잡하게 생겼지만, 그냥 Link를 NavLink로 대체해준 것 뿐이다.
isActive 여부를 판단하는 걸 포함한 삼항연산자를 넣어 미리 지정해둔 스타일을 적용할지 말지를 정한다.
즉 isActive ? activeStyle : undefined이다.
해당 게시글을 클릭해서 보고 있을 때, isActive가 활성화되고, 미리 지정해 둔 스타일이 적용된다.
여기서 리팩토링도 가능하다.
이렇게 반복되는 코드를 줄일 수 있다.
6.3 NotFound 페이지 만들기
이 페이지는 사전에 정의되지 않는 경로에 진입 시 띄우는 페이지이다.
src/pages/NotFound.js | src/App.js |
여기서 * 는 와일드카드 문자인데, 아무 텍스트나 매칭한다는 뜻이다.
즉, 위에 있는 라우트들을 모두 확인하고, 없다면 이걸 띄운다는 뜻.
테스트를 위해 URL을 아무거나 입력했다.
성공
6.4 Navigate 컴포넌트
Navigate컴포넌트는 컴포넌트를 화면에 보여주는 순간 다른 페이지로 이동을 하고 싶을 때 쓴다.
즉, 페이지를 리다이렉트 시 쓴다.
예를 들어, 사용자 로그인이 필요한데, 로그인을 안 했다면 로그인 페이지를 보여줘야 한다. 이럴 때 쓸 수 있다.
src/pages/Login.js | src/pages/MyPage.js | src/App.js |
isLoggedIn 값이 false, 즉, 로그인을 안했을 시, login 페이지로 이동한다.
replace를 true로 해서 현재 페이지를 기록에 남기지 않는다. 이러면 로그인 창에서 뒤로가기를 누르면 2페이지 이전으로 이동한다.
/mypage이동 시도 시 바로 login 페이지로 이동한다.
이로써 학기초 부터 시작했던 리액트 스터디가 끝이 났다.
스터디를 이끌어주신 스터디장분들과 함께 스터디를 진행해온 스터디원분들 모두 감사드리며 수고하셨습니다 :)
'WINK-(Web & App) > React.js 스터디' 카테고리의 다른 글
[2024 React.js 스터디] 류상우 #7주차 (0) | 2024.07.07 |
---|---|
[2024 React.js 스터디] 박지민 #마지막주차 "API 연동과 라우터" (0) | 2024.06.30 |
[2024 React.js 스터디] 김지나 #7주차 (0) | 2024.06.02 |
[2024 React.js 스터디] 이서영 #6주차 (0) | 2024.05.28 |
[2024 React.js 스터디] 류상우 #6주차 (0) | 2024.05.28 |