nextjs

Recoil은 무엇인가?

순9 2024. 7. 17. 14:39
728x90

Redux, Context API, useState처럼 상태관리

 

- 1. atom에 기본적인 틀만 있고, selector에서 초기값에 맞춰서 반환하는 경우

- 2. atom에 데이터가 다 있고, 각각의 selector에서 다른 데이터를 가져오는 경우

 

순서

1. atom 정의 -> 2. selector 정의 -> 3. 상태 업데이트 및 읽기(컴포넌트에서 아톰 연동)

-> 4. 아톰에 들어 온 값이 selector 에게 전달 -> 5. selector 는 들어 값에 추가 계산 또는 읽어 옴 

Recoil

- 페이스북에서 개발한 상태 관리 라이브러리

- 컴포넌트 기반으로 상태를 관리할 수 있는 기능을 제공

 

Recoil에서 상태는 atom과 selector로 관리

RecoilRoot 설정

예시

// pages/_app.js
import { RecoilRoot } from 'recoil';

function MyApp({ Component, pageProps }) {
  return (
    <RecoilRoot>
      <Component {...pageProps} />
    </RecoilRoot>
  );
}

export default MyApp;

 

- atom(기본 상태) : 상태의 단위 / 단순한 값을 저장

예시

import { atom } from 'recoil';

export const countState = atom({
  key: 'countState', // 각 atom의 고유 key
  default: 0, default: 0, // 기본값
});

 

- selector(파생 상태) : 아톰의 상태를 기반으로 새로운 값을 계산 / 캐싱을 통해 성능을 최적화하고 / 비동기 데이터를 처리

예시

import { selector } from 'recoil';
export const doubleCounterState = selector({
  key: 'doubleCounterState',
  get: ({ get }) => {
    const count = get(counterState);
    return count * 2;
  },
});

- 원본유지 아톰에 영향을 주지 않고 파생된 셀렉터에서 새롭게 계산하여 다른 값을 반환

- 파생 상태는 원본 상태가 변경될 때마다 자동으로 업데이트

- 캐싱 셀렉터는 동일한 입력에 대해 캐싱을 수행하여 성능을 최적화

 

컴포넌트 활용

import { useRecoilValue, useRecoilState } from 'recoil';
import { countState, doubleCountState } from './path/to/your/states';

function Counter() {
  const [count, setCount] = useRecoilState(countState);
  const doubleCount = useRecoilValue(doubleCountState);

  return (
    <div>
      <h1>Count: {count}</h1>
      <h2>Double Count: {doubleCount}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
}

export default Counter;

 

 

문자, 데이터일 경우

1. RecoilRoot 설정

// pages/_app.js
import { RecoilRoot } from 'recoil';

function MyApp({ Component, pageProps }) {
  return (
    <RecoilRoot>
      <Component {...pageProps} />
    </RecoilRoot>
  );
}

export default MyApp;

 

2. atom

// states/userState.js
import { atom } from 'recoil';

export const userState = atom({
  key: 'userState',
  default: {
    name: '',
    age: 0,
    email: ''
  },
});

 

3. selector

// states/userSelector.js
import { selector } from 'recoil';
import { userState } from './userState';

export const userNameState = selector({
  key: 'userNameState',
  get: ({ get }) => {
    const user = get(userState);
    return user.name;
  },
});

 

4. 컴포넌트 활용

// components/UserProfile.js
import { useRecoilState, useRecoilValue } from 'recoil';
import { userState, userNameState } from '../states/userState';

function UserProfile() {
  const [user, setUser] = useRecoilState(userState);
  const userName = useRecoilValue(userNameState);

  const updateName = (e) => {
    setUser({ ...user, name: e.target.value });
  };

  return (
    <div>
      <h1>User Profile</h1>
      <p>Name: {userName}</p>
      <input type="text" value={user.name} onChange={updateName} placeholder="Enter your name" />
    </div>
  );
}

export default UserProfile;

----------------------------------------------------------------------------------------------------------------------------------------------------------

4. 비동기 데이터 패싱

// states/todoListState.js
import { atom, selector } from 'recoil';
import axios from 'axios';

export const todoListState = atom({
  key: 'todoListState',
  default: [],
});

export const todoListQuery = selector({
  key: 'todoListQuery',
  get: async () => {
    const response = await axios.get('/api/todos');
    return response.data;
  },
});

 

 

5. 다중 selector

// states/shoppingCartState.js
import { atom, selector } from 'recoil';

export const cartItemsState = atom({
  key: 'cartItemsState',
  default: [],
});

export const cartTotalState = selector({
  key: 'cartTotalState',
  get: ({ get }) => {
    const items = get(cartItemsState);
    return items.reduce((total, item) => total + item.price * item.quantity, 0);
  },
});

 

1. useRecoilState

useState와 유사하게 동작하며, 상태 값을 읽고 업데이트할 수 있는 튜플을 반환

 

2. useRecoilValue

useRecoilValue는 아톰이나 셀렉터의 값을 읽기만 할 때 사용

 

3. useSetRecoilState

useSetRecoilState는 상태 값을 설정하는 데 사용됩니다. 상태 값을 읽지 않고도 업데이트