반응형
React-News Web App 에 Recoil 적용하기
기존에 react hook 방식과 redux-saga 를 적용해 만든 HackerRank News Web App 을 Recoil 을 이용해 상태를 관리하는 방식으로 다시 제작해봤습니다.
HackerRank News OpenAPI 를 활용했습니다.
실행 화면
Code
Recoil 초기 설정
먼저 npm i recoil
을 통해 recoil 을 설치합니다.
Recoil 은 Redux 와 비교하면 초기설정이랄 것도 없습니다.
import { RecoilRoot } from "recoil";
function App() {
return (
<>
<RecoilRoot>
<React.Suspense fallback={<div>Loading...</div>}>
<Router>
<ToolBar />
<Routes>
...
</Routes>
</Router>
</React.Suspense>
</RecoilRoot>
</>
);
}
그냥 RecoillRoot 로 감싸주면 끝입니다. 너무 좋습니다.
atom.js
import { atom } from "recoil";
export const pathNameState = atom({
key: "pathNameState",
default: "/",
});
export const askIDState = atom({
key: "askIDState",
default: 0,
});
export const userIDState = atom({
key: "userIDState",
default: 0,
});
atom.js 에는 상태가 변화함에 따라 api 를 호출하면서 각각 다른 파라미터를 넘겨주어야 할 때 필요한 변수들을 선언했습니다.
pathNameState 는 기존의 NewsList.js, JobsList.js, AskList.js 3가지 파일들을 ListItem.js 로 통합하면서 url 주소에 따라 News, Ask, Jobs 각각의 정보를 표시해주기 위해 선언했습니다.
selector.js
import { selector } from "recoil";
import { fetchAsk, fetchItem, fetchJobs, fetchNews, fetchUser } from "../api";
import { askIDState, pathNameState, userIDState } from "./atoms";
export const getItemList = selector({
key: "getItemList",
get: async ({ get }) => {
let path = get(pathNameState);
let response;
if (path === "/news" || path === "/") {
response = await fetchNews();
} else if (path === "/ask") {
response = await fetchAsk();
console.log(response.data);
} else if (path === "/jobs") {
response = await fetchJobs();
}
return response.data;
},
});
export const getAskInfo = selector({
key: "getAskInfo",
get: async ({ get }) => {
let askId = get(askIDState);
let response = await fetchItem(askId);
return response.data;
},
});
export const getUserInfo = selector({
key: "getUserInfo",
get: async ({ get }) => {
let userId = get(userIDState);
let response = await fetchUser(userId);
return response.data;
},
});
selector 함수는 atom.js 에서 선언한 변수의 상태가 변화하는 것을 감지할 수 있습니다.
유저 상세페이지, 질문글 상세페이지 등 호출할때마다 다른 ID값을 넘겨주어야 하는 경우에는 위 코드처럼 atom.js 에서 선언한 ID 값들을 구독(?) 하면 됩니다.
ListItem.js
import React, { useEffect } from "react";
import { Link, useLocation } from "react-router-dom";
import { useRecoilState, useRecoilValue } from "recoil";
import { pathNameState } from "../../state/atoms";
import { getItemList } from "../../state/selector";
export function ListItem() {
const { pathname } = useLocation();
const [pathName, setPathName] = useRecoilState(pathNameState);
const ItemList = useRecoilValue(getItemList);
useEffect(() => {
setPathName(pathname);
});
return (
<>...</>
)
- 현재 url 의 경로인 pathname 값을 atom.js 에서 선언한 pathNameState 에 넣어줍니다.
- 그러면 useRecoilValue 로 selector.js 의 getItemList 함수를 호출합니다.
- 마지막으로 selector.js 의 getItemList 함수에서는 변화한 state 값을 인지해 해당되는 데이터를 요청한 뒤 받아오게 됩니다.
전체 코드 보러가기
3.recoil 브랜치를 통해 코드를 확인하실 수 있습니다.
GitHub
반응형
'Study > React' 카테고리의 다른 글
Next.js + TypeScript ) 스크롤 내릴 시에 특정 컴포넌트 숨기기 (0) | 2022.07.15 |
---|---|
Next.js ) Input 입력값 태그로 변환하기 (TypeScript) (0) | 2022.07.15 |
React ) redux-saga 기반 api 호출 연습 (1) | 2022.05.11 |
React ) HackerNews WebApp 제작을 통한 React 학습 (0) | 2022.05.07 |
React ) Class 형 보다 Hook(함수) 형을 권장하는 이유 (0) | 2022.05.06 |
댓글