[원티드] 5월9일 TIL

eaasurmind·2022년 5월 9일
0

TIL

목록 보기
6/27

Recoil

Recoil을 사용하면 atoms (공유 상태)에서 selectors (순수 함수)를 거쳐 React 컴포넌트로 내려가는 data-flow graph를 만들 수 있다. Atoms는 컴포넌트가 구독할 수 있는 상태의 단위다. Selectors는 atoms 상태값을 동기 또는 비동기 방식을 통해 변환한다.

본래 react에서 상태관리를 할 때 state를 부모에서 자식으로 넘겨주는 구조여서 상당한 어려움을 겪었다.

recoil은 atom이라 불리는 state를 구독하고 있는 모든 컴포넌트에 접근해 상태를 관리할 수 있는 라이브러리입니다.
기존 react useState와 매우 흡사한 방식이어서 redux보다 더 배우기 간편한 점이 장점인 것 같습니다.
고유한 키 값을 지닌 atom이 변경되면 구독하고 있던 모든 컴포넌트들의 state가 새로운 값으로 리렌더 됩니다.

Atoms

Atoms는 상태의 단위이며, 업데이트와 구독이 가능하다. atom이 업데이트되면 각각의 구독된 컴포넌트는 새로운 값을 반영하여 다시 렌더링 된다. atoms는 런타임에서 생성될 수도 있다. Atoms는 React의 로컬 컴포넌트의 상태 대신 사용할 수 있다. 동일한 atom이 여러 컴포넌트에서 사용되는 경우 모든 컴포넌트는 상태를 공유한다.

Atoms는 atom함수를 사용해 생성하고
useRecoilState를 이용해 불러온다.

Selectors

Selector는 atoms나 다른 selectors를 입력으로 받아들이는 순수 함수(pure function)다. 상위의 atoms 또는 selectors가 업데이트되면 하위의 selector 함수도 다시 실행된다. 컴포넌트들은 selectors를 atoms처럼 구독할 수 있으며 selectors가 변경되면 컴포넌트들도 다시 렌더링된다.

Selectors는 상태를 기반으로 하는 파생 데이터를 계산하는 데 사용된다. 최소한의 상태 집합만 atoms에 저장하고 다른 모든 파생되는 데이터는 selectors에 명시한 함수를 통해 효율적으로 계산함으로써 쓸모없는 상태의 보존을 방지한다.
Selectors는 어떤 컴포넌트가 자신을 필요로하는지, 또 자신은 어떤 상태에 의존하는지를 추적하기 때문에 이러한 함수적인 접근방식을 매우 효율적으로 만든다.
컴포넌트의 관점에서 보면 selectors와 atoms는 동일한 인터페이스를 가지므로 서로 대체할 수 있다.

공식 문서의 예시로 투두앱을 만든다고 가정하였을 때,
리스트의 필터 옵션을 "Show All", "Show Completed"과 "Show Uncompleted"로 설정해준다고 하면

const todoListFilterState = atom({
  key: 'todoListFilterState',
  default: 'Show All',
});

selector내부에서는 todoListState와 todoListFilterState를 들고 오고있기 때문에 둘 중 하나라도 값이 바뀌면 selector가 재실행되어서 업데이트를 해준다.

const filteredTodoListState = selector({
  key: 'filteredTodoListState',
  get: ({get}) => {
    const filter = get(todoListFilterState);
    const list = get(todoListState);

    switch (filter) {
      case 'Show Completed':
        return list.filter((item) => item.isComplete);
      case 'Show Uncompleted':
        return list.filter((item) => !item.isComplete);
      default:
        return list;
    }
  },
});

컴포넌트에서는 한 줄로 간편히 관리가 되니 편리하다.

function TodoList() {
  // changed from todoListState to filteredTodoListState
  const todoList = useRecoilValue(filteredTodoListState);

  return (
    <>
      <TodoListStats />
      <TodoListFilters />
      <TodoItemCreator />

      {todoList.map((todoItem) => (
        <TodoItem item={todoItem} key={todoItem.id} />
      ))}
    </>
  );
}

TodoListFilters 컴포넌트에서는 filter값을 set해주는 로직과 구현 화면을 짜준다.

function TodoListFilters() {
  const [filter, setFilter] = useRecoilState(todoListFilterState);

  const updateFilter = ({target: {value}}) => {
    setFilter(value);
  };

  return (
    <>
      Filter:
      <select value={filter} onChange={updateFilter}>
        <option value="Show All">All</option>
        <option value="Show Completed">Completed</option>
        <option value="Show Uncompleted">Uncompleted</option>
      </select>
    </>
  );
}
profile
You only have to right once

0개의 댓글