문제 상황
회원 가입 폼을 만들던 중 발생한 문제이다. 로컬 스토리지에 값이 저장 되지 않는다
SSO 로그인을 해서 구글에서 유저 정보를 가져오면, 로컬 스토리지에 저장한다
그 후, 회원 정보를 등록 할 때, 저장된 정보를 가져오는 단순한 로직이다
- 로그인 페이지
setStorage("#user", JSON.stringify(data));
- getStorage/setStorage
// Function to store a string value in local storage using AES encryption
export function setStorage(key: string, value: string) {
const storage = new LocalStorage(); // Create a new instance of the typescript-web-storage library
const data = CryptoJS.AES.encrypt(value, SECRET_KEY); // Use the CryptoJS AES function to encrypt the input value
storage.setItem<string>(key, data.toString()); // Store the encrypted value in local storage
}
// Function to retrieve a previously stored string value from local storage
export function getStorage(key: string) {
const storage = new LocalStorage(); // Create a new instance of the typescript-web-storage library
const data = CryptoJS.AES.decrypt(
storage.getItem<string>(key) ?? "", // Retrieve the stored value, if it exists
SECRET_KEY
).toString(CryptoJS.enc.Utf8); // Use the CryptoJS AES function to decrypt the stored value
return data; // Return the decrypted value
}
해결 : 상태 관리
import { atom, AtomEffect } from "recoil";
import { getStorage, setStorage } from "utils/SecureStorage";
const localStorageEffect =
(key: string) =>
({ setSelf, onSet }: any) => {
const savedValue = getStorage(key);
if (savedValue !== null) {
setSelf(savedValue);
}
onSet((newValue: any, _: any, isReset: boolean) => {
console.log("new Value : ", newValue);
setStorage(key, JSON.stringify(newValue));
console.log("newvalue, isReset : ", newValue, isReset);
});
};
export const userState = atom({
key: "userState",
default: getStorage("#user") || null,
effects: [localStorageEffect("#user")],
});
먼저 userState를 선언한다. 이제 유저 데이터를 가져올 때 기본 값으로, storage 값을 가져온다.
recoil의 atom는 리액트의 state 처럼 사용 가능하다.
userState의 effects 부분이 핵심으로 useEffect와 비슷한 기능을 한다.
localStorageEffect는 state 값의 변화가 생길 경우, 작동한다
#user
값이 변경 될 경우, 앞서 만들어뒀던 setStorage에 string 형식으로 데이터를 입력하고, 로컬 스트리지에 저장한다
마치며
recoil을 사용하면 가볍게 상태 관리를 할 수 있다.
useEffect 로그를 찍어보면, 생각보다 자주 실행 되는 것을 보는데, useEffect 없이 recoil을 사용하는 것도 괜찮을 듯하다
const Login = () => {
const [storedUser, setStoredUser] = useRecoilState(userState);
const navigate = useNavigate();
const handleLoginSuccess = async (code: string) => {
const { data } = await axios.post(
"http://localhost:4000/auth/google/callback",
{ code }
);
setStoredUser(data);
const { status } = data;
const { ssoid, userid } = data;
if (status == "REGISTER") {
//TODO: 회원 가입 폼 이동
console.log("회원 가입하시죠");
navigate("/register");
} else {
//TODO: 바로 로그인
console.log("로그인 process 진행하시죠");
const result = await axios.post(
"http://localhost:4000/auth/token",
{
userid: userid,
ssoid: ssoid,
},
{ withCredentials: true }
);
console.log("result : ", result);
// navigate("/");
}
};
};
728x90
'DEV > Frontend' 카테고리의 다른 글
Base64 (0) | 2023.05.13 |
---|---|
React Rout로 Login Redirect 하는 방법 (0) | 2023.02.15 |
React 서버에서 잘 보낸 쿠키가 저장 되지 않는다 feat fastify (0) | 2023.02.09 |
React state는 뭔가 (0) | 2023.02.08 |
React Error Rendered more hooks than during the previous render (0) | 2023.02.08 |