Skip to main content

Command Palette

Search for a command to run...

[ 살펴보기 ] Recoil - Atom

[ 살펴보기 ] State Management Series - Recoil

Updated
3 min readView as Markdown
[ 살펴보기 ] Recoil - Atom
C

A developer living in Busan, Korea

Recoil은 atom과 selector를 통해 global state 관리를 도와준다

Atom은 Recoil에서 하나의 state을 구성하는 단위이며 수정 가능한 RecoilState object를 반환한다.

Atom

위에서 언급했듯이 atom은 state를 구성하는 단위다. 그렇기에 해당 atom을 subscrube하거나 update할 수 있으며 만약에 atom에 update가 발생하면 해당 atom을 subscribe하고 있는 component 역시 re-render된다

Atom은 다음과 같은 형태로 작성할 수 있다

import { atom } from "recoil";

export const userIdState = atom({
  key: "userIdState",
  default: 2,
});

여기서 주의해야 할 점은 atom을 선언할 때 사용하는 key가 다른 atom과 중복되지 않는 unique한 key여야 한다

그리고 다음과 같이 선언한 atom을 읽고 수정할 수 있다, 예제에서 볼 수 있듯이 일반 hook과 사용하는 방법이 거의 동일하다

import { useRecoilState } from "recoil";
import { userIdState } from "@/states/user";

const User = () => {
  const [userId, setUserId] = useRecoilState(userIdState);
  return (
    <div>
      <h3>User</h3>
      <div>{userId}</div> 
      <div>
        <button
          onClick={() => { setUserId(2) }}
        >
          Update user id
        </button>
      </div>
    </div>
  );
}

Default Value

Atom의 default value는 정적인 값이 될 수도 있고 혹은 다른 atom이나 selector를 default 값으로 사용할 수 있다. 만약 default로 다른 atom이나 selector를 사용했다면 사용된 atom / selector가 추후에 변경 되더라도 default로 해당 atom / selector를 쓰고 있는 atom의 값에는 영향을 주지않는다

정적은 값을 default로 사용하는 예제는 다음과 같다

export const userListState = atom<UserAtom[]>({
  key: "userListState",
  default: [{ name: "test", age: 0 }],
});

그리고 다른 atom의 값을 default value로 사용하는 예제는 다음과 같다

export const userListDefaultState = atom({
  key: "userListDefaultState",
  default: [{ name: "test", age: 0 }],
});

/*
  추후 userListDefaultState atom이 변경되더라도 
  userListState atom의 값엔 영향을 주지 않는다
*/
export const userListState = atom({
  key: "userListState",
  default: userListDefaultState,
});

그리고 만약 atom에 default prop 자체를 전달하지 않으면 atom의 상태는 pending이 되므로 주의하자

// atom의 state는 pending이 된다
export const userListState = atom({
  key: "userListState",
});

With typescript

이번에는 atom에 type을 선언하여 사용해보자

import { atom } from "recoil";

type UserState = {
  id: string;
  name: string;
  address: string;
  age: number;
};

export const userState = atom<UserState>({
  key: "userState",
  default: undefined,
});
import { useRecoilState } from "recoil";
import { userState } from "@/states/user";

const User = () => {
  const [user, setUser] = useRecoilState(userState);
  return (
    <div>
      <h3>User</h3>
      // user.name 정보 읽기
      <div>name : {user ? user.name : ""}</div>
      <div>
        <button
          onClick={() => {
            // user 정보 업데이트
            setUser({
              id: "a1",
              address: "test address",
              age: 25,
              name: "test name",
            });
          }}
        >
          Update User
        </button>
      </div>
    </div>
  );
};

위의 예제와 같이 useRecoilState hook를 통해 atom data와 update를 위한 setter function 둘 다 사용할 수 있지만 데이터 read만 필요한 상황이라면 useRecoilValue hook을 그리고 update만 필요한 상황이라면 useSetRecoilState hook을 사용할 수도 있다

read를 위한 useRecoilValue hook 예시

import { useRecoilValue } from "recoil";
import { userState } from "../../states/user";

const User = () => {
  const user = useRecoilValue(userState);
  return (
    <div>
      <h3>User</h3>
      <div>name : {user ? user.name : ""}</div>
    </div>
  );
};

Update를 위한 useSetRecoilState hook 예시

import { useSetRecoilState } from "recoil";
import { userState } from "../../states/user";

const User = () => {
  const setUser = useSetRecoilState(userState);
  return (
    <div>
      <h3>User</h3>
      <div>
        <button
          onClick={() => {
            setUser({
              id: "a1",
              address: "test address",
              age: 25,
              name: "test name",
            });
          }}
        >
          Update User
        </button>
      </div>
    </div>
  );
};

More from this blog

[ 살펴보기 ] TypeORM - Transactions, Migration

Transation Database 종류에 따라 detail한 부분은 차이점이 조금씩 있겠지만 각 sql statement는 개별적인 transaction block을 통해 실행되며 Database 설정에 따라 sql statement의 실행 결과가 자동으로 commit되어 영구히 적용되거나 commit을 직접 실행하기 전까지는 영구히 적용되지 않을 수 있다. 대부분의 경우 default로 sql statement 실행 결과가 자동으로 comm...

Feb 9, 20256 min read
[ 살펴보기 ] TypeORM - Transactions, Migration

Dev Diary

184 posts