facebookexperimental / Recoil

Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.
https://recoiljs.org/
MIT License
19.5k stars 1.18k forks source link

recoil state getting reset after auth with different platforms #2310

Open doubleA411 opened 3 months ago

doubleA411 commented 3 months ago

here is the login code

'use client'
import { useRecoilValue } from "recoil";
import { spotifyAtom, youtubeAtom } from "../recoil/atom";
import Link from "next/link";

function AuthButton() {

const spotify = useRecoilValue(spotifyAtom);
const youtube = useRecoilValue(youtubeAtom);
 console.log(spotify,youtube)

  return (
    <div className=" flex gap-5">
      {Object.keys(spotify).length > 0 ? (
        "Logged in Spotify"
      ) : (
        <Link
          href={
            "https://app.musicapi.com/shareplay/spotify/auth?returnUrl=http://localhost:3000/callback/spotify"
          }
        >
          Login to Spotify
        </Link>
      )}
      {Object.keys(youtube).length > 0 ?
       (
         "Logged in Youtube "
       )
       : 
       (
        <Link
          href={
            "https://app.musicapi.com/shareplay/youtube/auth?returnUrl=http://localhost:3000/callback/youtube"
          }
        >
          Login to Youtube Music
        </Link>
      )
      }
    </div>
  );
}

export default AuthButton;

code for setting the states

"use client";
import { useEffect } from "react";
import { useSetRecoilState } from "recoil";
import { spotifyAtom, youtubeAtom } from "../../recoil/atom";
import {  useSearchParams } from "next/navigation";
import Link from 'next/link'

function Page({params}) {
  const searchParams = useSearchParams();

  const setData =
    params.slug === "spotify"
      ? useSetRecoilState(spotifyAtom)
      : useSetRecoilState(youtubeAtom);

  useEffect(() => {

    const data64 = searchParams.get("data64");
    if (data64) {
      const decodedData = atob(data64);
      const jsonData = JSON.parse(decodedData);
      setData(jsonData);

    } else {
      console.log("No data found..")
    }
  }, []);

  return (
    <div className=' flex flex-col '>
      Successfully Logged in to {params.slug}
      <br/>
      <Link href="/dashboard">Go to Dashboard</Link>
    </div>
  );
}

export default Page;

when i first log in to spotify, it works fine and the state is set, and another state is empty, but when i log into youtube after spotify, the state of spotify gets empty and only youtube's state is there.

is there anything im doing wrong ?!

here's the atoms,

import { atom } from "recoil";

export const spotifyAtom = atom({
  key: "spotify",
  default: {},
});
export const youtubeAtom = atom({
  key: "youtube",
  default: {},
});
kis0421 commented 3 months ago

I think that's the right move Because, I don't know exactly the entire code of the service, but looking at the imported contents, Next.js and recoil are used together.

However, if you use Next.js your states will disappear when the browser refreshes.

Of course, initialization is possible if the browser refreshes and uses the newly received state from the server as the initializeState of RecoilRoot.