우리는 API와 의미 및 동작을 가능한 React답게 유지하면서 이것을 개선하고자 한다.
Recoil은 직교(orthogonal)하지만 본질적인 방향 그래프를 정의하고 React 트리에 붙인다. 상태 변화는 이 그래프의 뿌리(atoms)로부터 순수함수(selectors)를 거쳐 컴포넌트로 흐르며, 다음과 같은 접근 방식을 따른다.
'토이 프로젝트를 위해 사람들을 모집하는 커뮤니티'를 구현하는 중에는, 클라이언트 스테이트로 사용해야하는 정보가 적고, 서버에서 가져와야하는 정보만 많아서 리덕스 툴킷 대신에 리코일을 사용해보기로 했다.
1. index.js에 RecoildRoot로 감싸기
<RecoilRoot>
<App />
</RecoilRoot>
2. 아톰(store와 비슷하다고 보면 됨)만들기
import { atom } from "recoil";
export const bookmarkState = atom({
key:'bookmarkState',
default:[]
})
import { useRecoilState } from "recoil";
import { bookmarkState } from "./atom/bookmarkatom";
const [bookmark, setBookmark] = useRecoilState(bookmarkState);
=> useState를 사용, 가공하는 방식을 동일하게 적용하면됨
1) useRecoilState
getter, setter를 다 사용하는 메소드
const [getter, setter] = useRecoiltState(state이름)
2) useRecoilValue
getter만 가져오는 메소드
const 변수이름 = useRocoilValue(state이름)
3) useResetRecoilState
state를 기본 값 (atom의 default값)으로 되돌려 놓는 메소드
4) Selector()
import axios from "axios";
import React from "react";
import { useState } from "react";
import { useQuery } from "react-query";
import { bookmarkState } from "./atom/bookmarkatom";
import { useRecoilState } from "recoil";
const Pocketmon = () => {
const [bookmark, setBookmark] = useRecoilState(bookmarkState);
const [index, setIndex] = useState(1);
const GetPockemons = () => {
return axios.get(`https://pokeapi.co/api/v2/pokemon/${index}`)
}
const pockemons = useQuery([index], GetPockemons)
const addBookmark = () => {
setBookmark((current) => [
...current,
{
id: getId(),
index: index,
name: pockemons.data.data.name,
image: pockemons.data.data.sprites.front_default
}
])
}
if (pockemons.isLoading) {
return (
<div style={{ textAlign: "center", marginTop: "20px" }}>
Loading . . .
</div>
)
}
return (
<div style={{ textAlign: "center", marginTop: "20px" }}>
<button onClick={() => setIndex((prev) => prev - 1)}> ⬅︎ </button>
<button onClick={() => setIndex((prev) => prev + 1)}> ➡︎ </button>
<button style={{ position: "absolute", right: "0", marginRight: "20px" }}
onClick={addBookmark}
>➕</button>
<h3>#{index}</h3>
<h2>{pockemons.data.data.name}</h2>
<img src={pockemons.data.data.sprites.front_default} alt="포켓몬 이미지" />
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr 1fr 1fr" }}>
{bookmark.map((content) => {
return (
<div style={{ display: "flex", flexDirection: "column" }} key={content.id}>
<div>
<h3>⭐️#{content.index}</h3>
<h3>{content.name}</h3>
</div>
<img src={content.image} alt="포켓몬 이미지" />
</div>
)
})}
</div>
</div>
)
}
let id = 1;
function getId() {
return id++;
}
export default Pocketmon;