이어지는 글
https://5ffthewall.tistory.com/72
[React] recoil로 전역 상태 관리하기
https://5ffthewall.tistory.com/71 [React] 리액트 context API의 리렌더링 방지를 통한 성능 최적화 하기 / useMemo 사용하기 https://5ffthewall.tistory.com/67 [React] 리액트 context API로 상태 관리 하기 Context API란? Context
5ffthewall.tistory.com
recoil의 개념을 담은 글이다! 개념에서 더 나아가 간단한 예제를 만들어 사용법에 익숙해지고자 한다.
Recoil을 사용하여 간단한 할 일 목록 애플리케이션 만들기
0. 예제 파일 생성
npm create-react-app (파일 이름)
create-react-app으로 예제 앱을 생성해준다.

1. recoil 모듈 설치
npm install recoil
yarn add recoil
둘 중 하나로 모듈을 설치해준다.

다음과 같이 json파일에 recoil 버전이 나오면 잘 설치가 된 것이다! 고고
2. atom.js 만들기
import { atom } from 'recoil';
export const todoListState = atom({
key: 'todoListState', // 아톰의 고유 식별자
default: [], // 기본값은 빈 배열
});
할 일 목록을 담을 atom을 만들어준다.
3. selector.js 만들기
import { selector } from 'recoil';
import { todoListState } from './atom';
export const completedTodoCountState = selector({
key: 'completedTodoCountState',
get: ({ get }) => {
const todoList = get(todoListState);
return todoList.filter((todo) => todo.completed).length;
},
});
완료된 할 일 수를 계산하는 selector을 만들어준다. 배열 길이로 할 일 수를 계산함!
get을 통해 todoListState 아톰의 값을 가져오고 완료된 할 일 수를 반환한다.
4. counter.jsx 만들기
import React from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { todoListState } from './atom';
import { completedTodoCountState } from './selector';
export default function Counter(){
const [todoList, setTodoList] = useRecoilState(todoListState);
const completedTodoCount = useRecoilValue(completedTodoCountState);
const addItem = () => {
setTodoList([...todoList, { text: `할 일 ${todoList.length + 1}`, completed: false }]);
};
const toggleItemCompletion = (index) => {
const newList = [...todoList];
newList[index] = { ...newList[index], completed: !newList[index].completed };
setTodoList(newList);
};
return(
<div>
<h1>할 일 목록</h1>
<button onClick={addItem}>할 일 추가</button>
<p>완료된 할 일 수: {completedTodoCount}</p>
<ul>
{todoList.map((todo, index) => (
<li key={index} onClick={() => toggleItemCompletion(index)} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.text}
</li>
))}
</ul>
</div>
);
}
- useRecoilState()를 사용하여 구독해서 값을 불러온다! todoListState는 atom에서 정의함
todoList 변수에는 현재 할 일 목록이 저장되고 setTodoList 함수를 통해 이 목록을 업데이트할 수 있음
- useRecoilValue()를 사용해 selector 값을 읽어온다! completedTodoCountState는 selector에서 정의함
completedTodoCount 변수는 완료된 할 일의 수가 저장 됨!
- addItem()함수 : 할 일 목록에 새 항목을 추가한다! 할 일 목록은 아까 atom에서 불러왔음
- toggleItemCompletion()함수 : 완료 여부 표시!
index를 인자로 받아 할 일 목록에서 해당하는 인덱스의 항목의 완료 여부를 변경함!
newList[index] = { ...newList[index], completed: !newList[index].completed };
index를 인자로 받아 할 일 목록에서 해당하는 인덱스의 항목의 완료 여부를 변경함!
해당 항목의 completed 속성을 반전 시켜 완료 여부를 변경한다
const newList = [...todoList];
기존 목록을 복사해 새로운 배열을 생성함
setTodoList(newList);
새로운 배열을 setTodoList에 넣어 recoil상태로 업데이트 시킴! useRecoilState로 값을 다시 써주는 것
이를 통해 컴포넌트는 새로운 상태를 반영하고 다시 렌더링 됨
5. App.js 수정
import React from 'react';
import Counter from './counter';
function App() {
return (
<Counter/>
);
}
export default App;
6. index.js 수정
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { RecoilRoot } from 'recoil';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<RecoilRoot>
<App />
</RecoilRoot>
);
reportWebVitals();
반드시 최상단에 RecoilRoot를 설정해야 한다!
App.js의 상단에 설정했더니 This component must be used inside a <RecoilRoot> component. 이런 오류가 발생했다.
완전 최상단에 위치해주면 오류 해결!

+ 컴포넌트 추가하기
recoil을 쓰는 이유 자체가 컴포넌트 간 데이터 공유인데 컴포넌트가 count밖에 없어서 아쉽다는 생각이 들어서 추가로 만들었다!
7. TotalCount.jsx 추가하기
import React from 'react';
import { useRecoilValue } from 'recoil';
import { completedTodoCountState } from './selector';
export default function TotalCount() {
const completedTodoCount = useRecoilValue(completedTodoCountState);
return (
<div>
<p>완료된 할 일 총 수: {completedTodoCount}</p>
</div>
);
}
컴포넌트 간 공유가 잘 되는지 간단하게 확인하기 위해 별 기능을 추가하진 않았다!
useRecoilValue()로 selector의 값만 받아온다!
7-1. App.js 수정하기
import React from 'react';
import Counter from './counter';
import TotalCount from './totalCounter';
function App() {
return (
<>
<Counter/>
<TotalCount/>
</>
);
}
export default App;
컴포넌트 추가를 해주면~

데이터를 잘 주고 받는 것을 확인할 수 있다!!!
왕
뿌듯하군!
사용된 코드는 깃허브를 확인하세욤
https://github.com/ssolfa/recoil-example?tab=readme-ov-file
GitHub - ssolfa/recoil-example: Recoil을 사용한 간단한 할 일 목록 애플리케이션
Recoil을 사용한 간단한 할 일 목록 애플리케이션. Contribute to ssolfa/recoil-example development by creating an account on GitHub.
github.com
이제 recoil 실전 적용하기만 하면 된다!!!
다음엔 context API로 상태 관리를 하고 있던 내 코드를 recoil로 바꿔볼 것이다!
recoil 딱 기다려~~~
이어지는 다음글 >> https://5ffthewall.tistory.com/74
[React] 리액트 context API를 recoil로 바꾸기 / 상태 관리 도구 변경하기
이어지는글 https://5ffthewall.tistory.com/73 [React] 리액트 recoil 예제 만들어 사용해보기 이어지는 글 https://5ffthewall.tistory.com/72 [React] recoil로 전역 상태 관리하기 https://5ffthewall.tistory.com/71 [React] 리액트
5ffthewall.tistory.com
'React' 카테고리의 다른 글
[React] 리액트 Redux 사용하기 + useState / Redux / Redux toolkit 비교하기 (2) | 2024.02.29 |
---|---|
[React] 리액트 context API를 recoil로 바꾸기 / 상태 관리 도구 변경하기 (0) | 2024.02.18 |
[React] recoil로 전역 상태 관리하기 (1) | 2024.02.18 |
[React] 리액트 context API의 리렌더링 방지를 통한 성능 최적화 하기 / useMemo 사용하기 (1) | 2024.02.18 |
[React] 리액트 context API로 상태 관리 하기 (1) | 2024.02.17 |