Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat!: implement untrack and rework injectors #170

Merged
merged 1 commit into from
Feb 8, 2025

Conversation

bowheart
Copy link
Collaborator

@bowheart bowheart commented Feb 8, 2025

@affects atoms, react, stores

Description

As per the v2 spec, effects should run immediately after atom evaluation by default. There's no need to wait for a setTimeout tick to run them. Users can wrap the callback in a setTimeout themselves if they really need to wait a tick. But also, they just pretty much never should.

Remove the old createInjector util. Replace it with injectPrevDescriptor and setNextDescriptor - two much more lightweight and flexible utils that essentially do the same thing.

Remove readInstance. Move its logic to injectSelf which was previously a direct alias of readInstance. Update all injectors to use injectSelf.

Remove injectValidate.

Implement a new untrack utility patterned after other signals libs like Solid. Use it in injectMemo and injectEffect to prevent their callbacks from tracking reactive dependencies for the containing atom instance.

Breaking Changes

The previously-deprecated injectValidate injector is now removed. Use this instead:

const self = injectSelf()
// in a callback:
self.invalidate()

The callbacks passed to injectMemo and injectEffect (with synchronous: true) now no longer track reactive dependencies. This is technically a breaking change, though it can be considered a bug that's now fixed.

Effects no longer wait a tick to run. This means that when accessing atoms statically, effects are already registered. This is technically a breaking change, but also can be considered a bug with previous behavior.

const effectAtom = atom('effect', () => {
  const state$ = injectSignal(1)

  injectEffect(() => {
    const cleanup = state$.on('change', console.log)

    return cleanup
  }, [])
  
  return state$
})

const effectNode = myEcosystem.getNode(effectAtom)

// previously, this would not have triggered the effect's `change` listener. Now it does:
effectNode.set(2)

@bowheart bowheart merged commit ec49c84 into master Feb 8, 2025
2 checks passed
@bowheart bowheart deleted the josh/injector-rework branch February 8, 2025 20:24
@bowheart bowheart mentioned this pull request Feb 11, 2025
53 tasks
@bowheart bowheart added this to the Zedux v2 milestone Feb 11, 2025
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant