Closed lulla-by closed 1 year ago
셀렉터 내부에서 onSnapshot을 사용하는 것은 적절하지 않습니다. 다른 방법으로 접근해야 합니다. 참고로 onSnapshot은 이벤트 구독(subscription)이므로 컴포넌트 최초 마운트 이후 1회 연결되어야 하며, 컴포넌트가 언마운트 될 때 해제(unsubscription)되어야 합니다.
아래와 같이 사용하는 것이 일반적입니다. 참고해보세요. 😃
function Component() {
// 아톰 상태 및 상태 업데이트 함수를 useRecoilState 훅으로 가져오기
const [questions, setQuestions] = useRecoilState(questionsState);
useLayoutEffect(() => {
// 컴포넌트 마운트 시점에 1회 onSnapshot 연결
const unsubscription = onSnapshot(collection(dbService, "question"), (snapshot) => {
const newCollections = snapshot.docs.map((item) => item.data());
// 변경이 감지되면 atom 상태 업데이트
setQuestions(newCollections);
});
// 컴포넌트 언마운트 시점에 연결된 onSnapshot 해제
return unsubscription;
}, []);
// question 컬렉션 데이터를 Firestore에서 가져오는 이벤트 리스너(함수)
const handleFetchQuestions = async () => {
const querySnapShot = await getDocs(collection(dbService, "question"));
const newQuestions = querySnapShot.docs.map((doc) => ({
...doc.data(),
}));
// atom 상태 업데이트
setQuestions(newQuestions);
}
return (
<>
<button type="button" onClick={handleFetchQuestions}>Question 컬렉션 가져오기</button>
{/* ... */}
</>
);
}
export Component;
아래는 선언된 questionsState 아톰입니다. 아톰 이펙트를 사용해 아톰 상태가 변경되면 Console 패널에 출력합니다.
export const questionsState = atom({
key: "questionsState",
default: [],
// 아톰 이펙트 : 아톰 상태가 변경되면 콜백 되는 함수 연결
effects: [
({onSet}) => {
// 아톰 상태가 변경되면 새 값을 Console 패널에 출력
onSet((newValue) => console.log('questionsState 아톰 상태 값: ', newValue));
},
],
});
질문 작성자
이예솔
문제 상황
프로젝트 저장소 URL
node_modules
폴더를 제외한 나머지를 압축해 이 곳에 첨부하세요. deco.zip환경 정보