Skip to content

Skip change trigger when resetting/deleting an observable after read #654

Description

@RodolfoSilva

I'm using a pattern to exchange values between reusable screens, such as pickers where the list itself is a full expo-router screen, and I need to pass values back and forth between two screens. For a while I was doing this with Jotai, but I'm now replacing Jotai/FlashList with the legend-* stack, so I was wondering if there's a way to skip the change trigger for a given operation.

Here's the custom hook I'm currently using:

import {ObservablePrimitive} from '@legendapp/state';
import {useLayoutEffect, useRef} from 'react';

export function useObserveExchangeValue<Value = unknown>(
  observable$: ObservablePrimitive<Value>,
  fn: (value: NonNullable<Value>) => void,
) {
  const fnRef = useRef(fn);
  useLayoutEffect(() => {
    fnRef.current = fn;
  });
  useLayoutEffect(() => {
    return observable$.onChange(({value}) => {
      if (!value) return;
      observable$.delete();
      fnRef.current?.(value);
    });
  }, [observable$]);
}

What I'm trying to figure out is whether there's a clean way to achieve the same result: react to changes on an observable, then clear the value right after reading it, without that cleanup firing another change trigger.

BTW, the migration has been smooth so far and the API design really clicked for me. Coming from Jotai, the observable model felt intuitive almost immediately, and the performance difference with reactive components has been noticeable in my screens. Thanks for the great work on this library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions