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.61k stars 1.18k forks source link

onSet is not triggered when using `useRecoilState` #2294

Open hyungjikim opened 1 year ago

hyungjikim commented 1 year ago

Hi, team.

I'm using recoil-persist to save atom in local storage.

I found out that onSet is not triggered when using useRecoilState. However, it is executed when using useSetRecoilState.

I'm using recoil 0.7.7, the latest version, and Next.js 12.3.2.

I looked through your document, describing onSet as Subscribe to changes in the atom value..

Below is the source code. Atom is updated, but it is not stored in the local storage.

import {atom} from "recoil";
import {recoilPersist} from "../utils/recoil-persist";

const {persistAtom} = recoilPersist()

const authAtom = atom({
    default: 'hj',
    key: 'authAtom',
    effects_UNSTABLE: [persistAtom],
})

const GNB = () => {
    const [auth, setAuth] = useRecoilState(authAtom);

    useEffect(() => {
        setAuth('eden')
    }, [])

    return (
        <div>
            <p>{auth}</p>
        </div>
    )
}

In my understanding, onSet should be called when the atom has new value (default: 'hj' -> new value: 'eden').

Using useSetRecoilState, however, it is saved in the storage.

const GNB = () => {
    const setAuth = useSetRecoilState(authAtom);

    return (
        <div>
            <p>{auth}</p>
        </div>
    )
}

Would you please let me know why onSet is not triggered when using useRecoilState? Or, is there anything that I misunderstood using useRecoilState and onSet?

Gamez0 commented 1 year ago

can you add the version of recoil-persist you use?

clockk commented 11 months ago

@hjk329 There are no issues with recoil-persist or onSet.

This is a problem that occurs very strictly in the mode. This is related to an issue where two connections are required to identify a bug in Strict mode. So in a production environment there will be no problem.

  1. Try removing the React.StrictMode component
  2. Try running it after building, not in dev mode.
  3. Run the setter within the cleanup function of useEffect.