Recoil 사용이유
원래는 redux를 사용했었는데 TypeScript로 처음 프로젝트를 하면서 redux를 적용하려니 너무 어려웠음
그래서 redux보다 간단하다는 recoil을 사용해보기로 결정!!
(실제로 훨씬 사용하기 수월했다)
Recoil 적용
1. 프로젝트에 Recoil 설치하기
npm i recoil
2. RecoilRoot로 App 컴포넌트 감싸주기
(index.tsx)
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') as HTMLElement
);
root.render(
<React.StrictMode>
<RecoilRoot>
<App />
</RecoilRoot>
</React.StrictMode>
);
reportWebVitals();
recoil을 사용하기 위해서는 부모 컴포넌트에 RecoilRoot가 필요하고, 루트 컴포넌트에 넣으면 좋다.
3. Atom
Atom은 recoil에서 사용하는 state를 나타낸다.
key에는 유니크한 key값을, defualt에는 default 값을 넣어준다.
(recoil/atoms.ts)
import { atom } from 'recoil';
export interface TodoTypes {
id: number;
text: string;
done: boolean;
}
export const todoState = atom<TodoTypes[]>({
key:"todos",
default:[],
});
4. Atom(state) 가져오고 수정하기 - useRecoilValue, useSetRecoilState, useRecoilState
useRecoilValue()는 atom에서 값을 읽어오고,
useSetRecoilState()는 atom의 값을 업데이트(설정) 해준다.
여기서는 사용하지 않았는데, useRecoilState()는 아래처럼 사용해서 atom의 값을 읽고, 업데이트할 수 있게 해준다.
const [text, setText] = useRecoilState(textState);
(todolist.tsx)
import React,{ useState, useEffect } from "react";
import TodoItem from "./todoItem";
import TodoInput from './todoInput';
import { TodoListContainer } from '../styles/todolist.styled'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { todoState, TodoTypes } from '../recoil/atoms';
const TodoList = () => {
const [todoInput, setTodoInput] = useState<string>('');
const todos = useRecoilValue<TodoTypes[]>(todoState);
const setTodos = useSetRecoilState<TodoTypes[]>(todoState);
const addItem = () => {
const nextId = todos.length > 0? todos[todos.length-1].id + 1 : 0;
const todo: TodoTypes = {
id: nextId,
text: todoInput,
done: false
}
setTodos([...todos, todo]);
setTodoInput('');
}
return(
<TodoListContainer>
<div
style={{paddingTop:"20px", fontSize:"25px"}}
>To-Do List</div>
<TodoInput
todoInput={todoInput}
setTodoInput={setTodoInput}
addItem={addItem}
/>
<TodoItem
todos={todos}
setTodos={setTodos}
/>
</TodoListContainer>
)
}
export default TodoList;
5. 새로고침 후에도 state 유지하기 - Recoil-persist
Recoil-persist는 새로고침했을 때, 데이터가 날라가지 않게 해주는 라이브러리로
localStorage 또는 sessionStorage에 데이터를 저장해준다.
recoilPersist안에 지정을 해주는데, 지정해주지 않으면 기본값으로 localStorage에 저장이 된다.
Recoil-persist를 적용하려면 atom안에 effects_UNSTABLE를 추가해주어야 한다.
* 저장할 곳을 지정해주고 싶으면 아래처럼 해주면 된다.
const { persistAtom } = recoilPersist({
key: '유니크한 키값',
storage: sessionStorage,
});
(recoil/atoms.ts)
import { atom } from 'recoil';
import { recoilPersist } from 'recoil-persist';
const { persistAtom } = recoilPersist();
export interface TodoTypes {
id: number;
text: string;
done: boolean;
}
export const todoState = atom<TodoTypes[]>({
key:"todos",
default:[],
effects_UNSTABLE: [persistAtom]
});