recoil 사용하기 (1) Create

minkyung·2022년 7월 5일
0

공식문서

📎 React를 위한 상태관리 라이브러리 Recoil

Motivation

우리는 API와 의미 및 동작을 가능한 React답게 유지하면서 이것을 개선하고자 한다.

Recoil은 직교(orthogonal)하지만 본질적인 방향 그래프를 정의하고 React 트리에 붙인다. 상태 변화는 이 그래프의 뿌리(atoms)로부터 순수함수(selectors)를 거쳐 컴포넌트로 흐르며, 다음과 같은 접근 방식을 따른다.

  • 우리는 공유상태(shared state)도 React의 내부상태(local state)처럼 간단한 get/set 인터페이스로 사용할 수 있도록 boilerplate-free API를 제공한다. (필요한 경우 reducers 등으로 캡슐화할 수도 있다.)
  • 우리는 동시성 모드(Concurrent Mode)를 비롯한 다른 새로운 React의 기능들과의 호환 가능성도 갖는다.
  • 상태 정의는 점진적이고(incremental) 분산되어 있기 때문에, 코드 분할이 가능하다.
  • 상태를 사용하는 컴포넌트를 수정하지 않고도 상태를 파생된 데이터로 대체할 수 있다.
  • 파생된 데이터를 사용하는 컴포넌트를 수정하지 않고도 파생된 데이터는 동기식과 비동기식 간에 이동할 수 있다.
  • 우리는 탐색을 일급 개념으로 취급할 수 있고 심지어 링크에서 상태 전환을 인코딩할 수도 있다.
  • 전체 애플리케이션 상태를 하위 호환되는 방식으로 유지하기가 쉬우므로, 유지된 상태는 애플리케이션 변경에도 살아남을 수 있다.

써보기

'토이 프로젝트를 위해 사람들을 모집하는 커뮤니티'를 구현하는 중에는, 클라이언트 스테이트로 사용해야하는 정보가 적고, 서버에서 가져와야하는 정보만 많아서 리덕스 툴킷 대신에 리코일을 사용해보기로 했다.

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()

React query와 함께 써본 전체 코드 (Create 함수)

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;
profile
프론트엔드 개발자

0개의 댓글