jotai: `useAtom` has something wrong when dynamic return an `atom`

Example:

import { atom } from 'jotai';
import { atomWithStorage, createJSONStorage } from 'jotai/utils';


export const isComparison = atomWithStorage('isComparison', false, createJSONStorage(() => sessionStorage) as any);

export const test = atom((get) => {
  const re = get(isComparison);
  const date = re ? new Date() : null;  
  return date;
})

atomWithStorage:

export function atomWithStorage<Value>(
  key: string,
  initialValue: Value,
  storage:
    | SyncStorage<Value>
    | AsyncStorage<Value> = defaultStorage as SyncStorage<Value>
) {
 //...
  const baseAtom = atom(storage.delayInit ? initialValue : getInitialValue())

  baseAtom.onMount = (setAtom) => {
    let unsub: Unsubscribe | undefined
    if (storage.subscribe) {
      unsub = storage.subscribe(key, setAtom)
    }
    if (storage.delayInit) {
      const value = getInitialValue()
      if (value instanceof Promise) {
        value.then(setAtom)
      } else {
        setAtom(value)
      }
    }
    return unsub
  }

  const anAtom = atom(
    (get) => get(baseAtom),
    (get, set, update: SetStateAction<Value>) => {
      const newValue =
        typeof update === 'function'
          ? (update as (prev: Value) => Value)(get(baseAtom))
          : update
      set(baseAtom, newValue)
      return storage.setItem(key, newValue)
    }
  )
// new atom;
  return anAtom
}

when useEffect:

 const [res] = useAtom(test);
  const [, setIsComparison] = useAtom(isComparison)
  useEffect(() => {
    setIsComparison(true);
  }, [setIsComparison])  

something goes wrong: image infinity update!

at useAtom:

useEffect(() => {
  store[COMMIT_ATOM](atom)
})
// It's missing dep array
useEffect(() => {
  store[COMMIT_ATOM](atom)
}, [store, atom])

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 24 (17 by maintainers)

Most upvoted comments

Hi @SquirrelJimmy have your issue been resolved?

After upgrading to 1.4.7 I falled into the same rabit hole and fix the version in 1.4.4 to resolve it. I wanna share a reproduction but cannot since my project is inside of my company and I cannot figure out a way to reproduce it neigther since the project is quite a large codebase.

I am happy to see 1.4.9 been released and head to try it but it gets worse. Previous the ‘Maximum update’ happened if I changed some states but now it happens once I open the page. So I revert to 1.4.4 again.

Will try to figure out a way to reproduce my ‘Maximum update’ issue.