Skip to content

Binding to observables that emit SUSPENSE with a default value does not trigger React.Suspense to render the fallback component #307

Description

@amydevs

Overview

I have a component that is using a returned hook from the bind function. Within the docs examples, they trigger a suspense component's fallback by starting with emitting the SUSPENSE symbol on the observable passed to the bind function. However, this does not work when I've passed a default value to bind.

The intention is to have a component that can have initial stale data that is to be hydrated from an observable

Recreation

I've first declared a signal and an asynchronous function:

   const [apiCall$, onApiCall] = reactRxjsUtils.createSignal();

    let i = 0;
    const f = (): Promise<number> => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(i++);
        }, 1000);
      });
    }

Here, I've followed the SUSPENSE page in the API docs in creating a hook, passing in an observable that should start with a value of suspense:

    const [useApiResult, apiResult$] = reactRxjsCore.bind(
      apiCall$.pipe(
        rxjsOperators.switchMap(
          () => concat(of(reactRxjsCore.SUSPENSE), from(f()))
        )
      ),
      null
    );

I've also tried this variation:

    const [useApiResult, apiResult$] = reactRxjsCore.bind(
      apiCall$.pipe(
        rxjsOperators.switchMap(
          () => from(f()).pipe(rxjsOperators.startWith(reactRxjsCore.SUSPENSE))
        )
      ),
      null
    );

And just only emitting SUSPENSE:

    const [useApiResult, apiResult$] = reactRxjsCore.bind(
      apiCall$.pipe(
        rxjsOperators.switchMap(
          () => of(reactRxjsCore.SUSPENSE)
        )
      ),
      null
    );

No matter whatever I do, except for removing the default null argument to bind, the fallback ("Loading...") is not shown when SUSPENSE is being emitted.

function Button() {
  const { onApiCall, useApiResult } = useService("test");
  const apiResult = useApiResult();
  React.useEffect(() => {
    if (apiResult == null) return;
    console.log(apiResult);
  }, [apiResult]);
  return (
    <button onClick={onApiCall}>Click me</button>
  );
}

function Test() {
  return 
  (
    <Subscribe fallback={"Loading..."}>
      <Button />
    </Subscribe>
  );
}

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