jotaijs / jotai-scope

MIT License
60 stars 4 forks source link

feat: add no-scope api to ScopeProvider #35

Closed dmaskasky closed 3 months ago

dmaskasky commented 6 months ago

Background

Unscoped derived atoms must be copied in a scope in case they depend on atoms that are scoped. This copy causes read side-effects such as fetch to rerun which may be undesirable. There is no way for developers to indicate that a derived atom does not depend on scoped atoms in the current api.

Proposed Solution

This PR proposes a new prop for ScopeProvider, noScope: Iterable<AnyAtom>. Passing atoms to this prop will declare them to be not dependent on any scoped atoms.

<ScopeProvider atoms={[]} noScope={[atomA]}>

Behavior

  1. ❌ If an atom is unscoped (derived, primitive, or writeOnly) and noScoped, it will NOT be cloned.
  2. ❌ If an atom is inherited from a scoped atom and noScoped, it will NOT be cloned.
  3. ✅ If an atom is explicitly scoped and noScoped, it will still be cloned.
  4. ✅ If an atom is implicitly scoped and noScoped, it will still be cloned.

Fixes:

Discussion

1. Should we instead export a utility to set this globally?

I think I'm still in favor of a noScope property on the ScopeProvider as it provides greater specificity.

export function noScope(anAtom: AnyAtom) {
  anAtom.noScope = true;
}

2. Should implicit dependencies adhere to noScope?

Should atomA be implicit scoped in the following example?

const atomA = atom(() => fetch(url))
const atomB = atom((get) => get(atomA))

function Component() {
  useAtom(atomB)
}

<ScopeProvider atoms={[atomB]} noScope={[atomA]}>
  <Component />
</ScopeProvider>

3. 💡 Another idea

Jotai exposes an api that describes the atom's current dependencies and notifies when dependencies change. Jotai Scope will determine if any of those dependencies are scoped to determine whether the atom needs to be copied or not.

4. 💡 Yet another idea

An atom's Getter and Setter are defined by the store and can be overwritten by jotai-scope. This eliminates the for copying unscoped derived atoms.

codesandbox-ci[bot] commented 6 months ago

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

dai-shi commented 6 months ago

I'd basically leave it to you guys. Let me know if exposing something from the store api might help. I can't guarantee if it will be accepted though.

dmaskasky commented 3 months ago

Update on this: we will not need to add a no-scope api if https://github.com/jotaijs/jotai-scope/pull/46 gets merged.

https://github.com/jotaijs/jotai-scope/pull/46 is in progress.

dmaskasky commented 3 months ago

I am exploring other directions to solve this use-case, closing this PR for now.