하단의 다크모드 버튼을 누르시면 좀 더 편안하게 보실 수 있습니다.
Recoil
React의 기존의 상태관리 라이브러리
component state는 공통된 상위요소까지 끌어올려야 공유가능 → 거대한 트리가 re-render 될 수 있다는 단점
Redux → 기본적인 store 구성을 위해 많은 보일러 플레이트와 많은 코드를 작성해야하는 단점
Context → single value만 저장할 수 있으며, 자체 consumer를 가지는 여러 값들의 집합을 담을 수 없다는 단점
이러한 단점을 해결하는 방안으로 facebook에서 만든 상태관리 라이브러리가 Recoil이다.
Recoil의 장점
1. 쉽다.
2. 비동기 데이터 흐름을 위한 내장 솔루션 제공
3. React 동시성 모드(Concurrent Mode) 지원 및 다른 새로운 React 기능과의 호환 가능성
설치
npm install recoil
yarn add recoil
RecoilRoot
recoil state를 사용할 컴포넌트의 부모 tree에 RecoilRoot가 필요하다.
import React from 'react';
import { RecoilRoot } from 'recoil';
import CahracterCounter from './CharacterCounter';
const App = () => {
return (
<RecoilRoot>
<CahracterCounter />
</RecoilRoot>
);
};
export default App;
Atoms & Selectors
기본 흐름
Atoms에서 selectors(순수함수)를 거쳐 React components로 내려가는 data-flow
Atom
- Atoms는 어떤 component에서나 읽고 쓸 수 있는 하나의 state를 의미한다. (상태의 단위, 업데이트와 구독 가능)
- Atom에 어떤 변화가 있으면 그 atom을 구독하는 모든 컴포넌트들은 re-rendering된다.
- Atom을 생성하기위해 고유한 key 값과 default값을 설정해준다.
- default값은 정적인 값, 함수, 비동기함수가 될 수 있다.
const textState = atom({
key: 'textState', // unique ID (with respect to other atoms/selectors)
default: '', // default value (aka initial value)
});
Selector
- Selector는 derived state(파생된 상태)의 일부를 나타낸다.
- 파생된 상태를 수정하는 pure function 순수함수에 전달된 상태의 결과물이다.
- 상위의 atoms, selectors가 업데이트 되면 하위의 selector 함수도 re-evalutated된다.
- 최소한의 state만 atoms에 저장하고 다른 모든 파생되는 데이터는 selectors에 명시한 함수를 통해 효율적으로 계산하여 불필요한 state의 보존을 방지한다.
//selector 함수로 정의한다.
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
//전달되는 get 인자를 통해 atoms와 다른 selectors에 접근가능
get: ({get}) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
🔻 Hook
- useRecoilState : 읽기/쓰기
- useRecoilValue : 읽기
- useSetRecoilState : 쓰기
useRecoilState
: atom 혹은 selector의 값을 읽고 쓸 때 사용한다.
useState와 동일하게 사용가능하다.
const [count, setCount] = useRecoilState(countState);
const increaseCount = () => {
setCount(count + 1);
}
[활용]
import React from 'react';
import { useRecoilState } from 'recoil';
import { todoListState } from '../recoil';
export const TodoItem = ({ item }) => {
const [todoList, setTodoList] = useRecoilState(todoListState);
const index = todoList.findIndex((listItem) => listItem === item);
const editItemText = ({ target: { value } }) => {
const newList = replaceItemAtIndex(todoList, index, {
...item,
text: value,
});
setTodoList(newList);
};
return (
<div>
<input type='text' value={item.text} onChange={editItemText} />
<input />
<button>X</button>
</div>
);
};
const replaceItemAtIndex = (todoList, index, newValue) => {
return [...todoList.slice(0, index), newValue, ...todoList.slice(index + 1)];
};
};
useRecoilValue
: Recoil state값을 반환한다. (읽기)
const count = useRecoilValue(countState);
[활용]
import React from 'react';
import { useRecoilValue } from 'recoil';
import { todoListState } from '../recoil';
import { TodoItem } from './TodoItem';
import { TodoitemCreator } from './TodoitemCreator';
export const TodoList = () => {
const todoList = useRecoilValue(todoListState);
return (
<>
<TodoitemCreator />
{todoList.map((item) => (
<TodoItem key={item.id} item={item} />
))}
</>
);
};
useSetRecoilState
: 내용을 업데이트하는 setter 함수에 접근한다. (쓰기)
const setCount = useSetRecoilState(countState);
import React, { useState } from 'react';
import { useSetRecoilState } from 'recoil';
import { todoListState } from '../recoil';
export const TodoitemCreator = () => {
const [inputValue, setInputValue] = useState('');
const setTodoList = useSetRecoilState(todoListState);
const handleInputChange = ({ target: { value } }) => {
setInputValue(value);
};
const addItem = () => {
setTodoList((oldList) => [
...oldList,
{
id: getId(),
text: inputValue,
inComplete: false,
},
]);
};
return (
<div>
<input type='text' value={inputValue} onChange={handleInputChange} />
<button onClick={addItem}>Add</button>
</div>
);
};
let id = 0;
function getId() {
return id++;
}
useResetRecoilState
: atom이나 selector의 값을 초기화
const resetCount = useResetRecoilState(countState);
...
<button onClick={resetCount}>reset count</button>
'Archive' 카테고리의 다른 글
[Git] Git 사용 기초 ( local-remote / branch-head / push-pull ) (0) | 2022.10.26 |
---|---|
[React] TDD in reactjs with RTL and Jest - (2)기초 예제 (0) | 2022.10.25 |
[RN] react-native-video (evaluating 'RCTVideolastance.Constants' error) (0) | 2022.08.27 |
[React] TDD in reactjs with RTL and Jest - (1) 기초 이론 (0) | 2022.08.08 |
[React] React Query로 서버 상태 관리 기초 개념 (0) | 2022.07.28 |