Closed SunNacho closed 1 year ago
브라우저가 아닌 서버에서 실행될 때 문제가 되는 것 같아서 찾아보니 recoil-persist
는 이런 방법으로 해결해주고 있는 것 같아요.
const localStorageEffect = () => {
if (typeof window === 'undefined') {
// 서버에서 실행되는 Effet 함수
return () => {};
}
// 브라우저에서 실행되는 Effect 함수는 여기에다 작성
// 여기에선 localStorage 접근 가능
}
atom({
effects: [localStorageEffect()]
})
effect함수에 사용되는 setSelf와 onSet을 어떻게 처리해야 할까요?? if(typeof window ==='undefined') {return ()=>{}} 를 atom effect함수 안에 넣어보기도 해봤지만 잘 안되네욤 ㅠㅠ
흠 한 번 요렇게 해볼래요? 반환 타입을 지정해주면 될 것 같아요
그리고 다른 곳에서도 범용적으로 쓰여야 하니까 스토리지에서 사용할 key 값, 사용할 스토어를 인자로 받으면 좋을 것 같아요ㅎㅎ
import { AtomEffect } from 'recoil'
function storageEffect<T = any>(key: string, storage: localStorage | sessionStorage = localStorage): AtomEffect<T> {
if (typeof window === 'undefined') {
return () => {};
}
return ({setSelf, onSet}) => {...}
}
atom({
effects: [localStorageEffect('favoriteList')]
})
제가 이해를 잘 한게 맞을까요? effects:[storageEffect('favoriteList',localstorage)라고 적는게 맞을까요...
아직은 같은 오류가 생깁니다
위의 빨간줄의 문제 해결 도움 양식에선 typeof localstorage를 쓰는 것을 추천하길래 그렇게 변경했더니
이렇게 나타납니담 ㅠ
아 맞네요 typeof
로 써야했네
그럼 옵션을 문자열로 받아서 사용하는 게 좋겠네요. 접근만 해도 오류가 나는구나.
import { AtomEffect } from 'recoil'
function storageEffect<T = any>(key: string, type: 'localStorage' | 'sessionStorage' = 'localStorage'): AtomEffect<T> {
if (typeof window === 'undefined') {
return () => {};
}
const storage = type === 'localStorage' ? localStorage : sessionStorage;
return ({setSelf, onSet}) => {...}
}
atom({
effects: [localStorageEffect('favoriteList')]
})
이제 경고줄은 없어졌습니다!! 그런데...
즐겨찾기 버튼을 누르면 여전히 favorites을 인식못하는 상황이네요 ㅠㅠ 코드는 pr에 올려놓은거에서 건들지 않았습니다
아무래도 현재 localStorage에 저장되어 있는 값의 형태가 배열이 아닌가보네요. 개발자 도구에 들어가서 다 지워볼래요?
아래처럼 정의하고 사용하니까 저는 잘 되더라구요.
function storageEffect<T>(key: string, type: 'localStorage' | 'sessionStorage' = 'localStorage'): AtomEffect<T> {
if (typeof window === 'undefined') {
return () => {};
}
const storage = type === 'localStorage' ? localStorage : sessionStorage;
return ({setSelf, onSet}) => {
const savedData = storage.getItem(key);
if (savedData) {
setSelf(JSON.parse(savedData));
}
onSet((newValue, _, isReset) => {
isReset ? storage.removeItem(key) : storage.setItem(key, JSON.stringify(newValue));
});
};
}
아..이미 저장된 타입과 충돌이 나서 그런걸까요? 이건 정말 혼자선 알아내기 너무 어려운 부분이었네요 ㅠㅠ 내일 근무지 도착하자마자 바로 검토해보겠습니다
하 확인했습니다 ㅠㅠ 드디어!!!!행복해
사진과 같이 effect 기능을 사용하여 atom과 storage를 연동했는데요, 이 상태에서 즐겨찾기 토글을 누르면 다음과 같은 오류가 뜹니다
favorites은 useRecoilValue로 읽은 데이터이고 switchdata는 data와 favorites을 선택하는 변수입니다.
또한 즐겨찾기 버튼을 누를 때에는 다음과 같은 오류가 뜹니다
effect부분을 삭제하고 다시 눌러보면 정상적으로 작동하는걸로 보아, effect를 사용한게 문제인것 같은데, 왜 저런 오류가 뜰까요? favorites의 타입을 인식하지 못하는 걸까요? 어떤 오류인지 감이 오지 않아 물어봅니다 ㅠ
참고로 effect에 있는 LocalStorage는 next.js에서 localstorage접근 시 뜨는 오류를 방지하기 위해 다음과 같이 클래스화 시켜 import한 함수입니다.
머리가 너무 아파용 ㅜㅜ살려주세요