노마드코더 react X firebase를 활용한 트위터 클론코딩을 진행하고 있었다. useState를 활용해 정보값들을 주고 받았는데, recoil을 적용해보고 싶었다. 2단계 뎁스 밖에 안되지만, 경험상 적용해보았다.
에러가 뙇! 왜안되지...
공식문서를 찾아보았다.
지난 번 프로젝트를 진행할 때도 recoil
을 끼얹어봤는데, 그 때도 자동으로 리렌더링되지 않은 문제 때문에 골머리를 앓았다. 혹시 그 문제일까 싶어서 dangerouslyAllowMutability
를 조금 더 찾아보았다.
비슷한 문제를 지닌 Github 이슈를 발견했다.
Uncaught TypeError: Cannot freeze
drarmstr 님의 조언으로 해결 할 수 있었다. 무슨 말인지 정확히는 모르겠지만, recoil
나름대로 데이터를 저장하는 흐름이 있다고 한다. 근데 저장된 값이 변이를 일으켜 변경을 시도하면 이를 추적하거나 업데이트 되지 않은 경우가 발생한다고 함.
그래서 deep freeze
기술로 이를 해결함.
근데 여기서도 변경 가능한 객체를 recoil
상태 변화를 논리적으로 표시되지 않은 값들을 사용해야하는 경우들이 생기는데, You can use the dangerouslyAllowMutability
option when constructing your atom to allow for this.
암튼 다 모르겠고, freeze가 안되는 경우가 생길 때 dangerouslyAllowMutability
옵션을 사용하라고 함.
암튼 변화를 알려주라고 공지하는 것 같다.
dangerouslyAllowMutability
- Recoil은 atom을 이용해 다시 렌더링 되는 컴포넌트에 언제 알려야 할지 알기 위해 atom의 상태 변화에 의존한다. 만약 atom의 값이 변경될 경우, 이를 거치지 않고 등록된 컴포넌트에 제대로 알리지 않고 상태가 변경될 수 있다. 이를 방지하기 위해 저장된 모든 값이 변경되지 않는다. 경우에 따라 이 옵션을 사용하여 이 옵션을 재정의할 수 있다.
그래서 atom.jsx
에 적용해보았다.
import { atom, selector } from "recoil";
export const userState = atom({
key: "userState",
default: "",
dangerouslyAllowMutability: true,
});
문제해결
recoil
이 정상 작동된다.
제대로 보고하는게 이래서 중요하다.
추가로 recoil
기본 사용법
상태를 정의할 때는 고유값인 key를 설정하고, 기본값(default)설정.
const [todoList, setTodoList] = useRecoilState(todoListState);
useRecoilValue(todoListState)는 상태 값만 필요할 경우에 사용하면 된다.
const todoList = useRecoilValue(todoListState);
useSetRecoilState(todoListState)는 상태를 업데이트하는 함수만 필요한 경우 사용하면 된다.
const setTodoList = useSetRecoilState(todoListState);