Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

(WIP) Suspense #96

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open

(WIP) Suspense #96

wants to merge 1 commit into from

Conversation

pshrmn
Copy link
Owner

@pshrmn pshrmn commented Aug 23, 2018

This is a work in progress to determine the API that should be used with React suspense

Prepping Curi to be ready for React Suspense. With Suspense, a navigation cannot be completed until after it has rendered.

When a router is created with the suspend: true option, the emitted navigation object will have a finish() function attached to it. The actual navigation (updating of the history) will not happen until that function is called.

const router = curi(history, routes, {
  suspend: true
});

router.respond(({ navigation }) => {
  // typeof navigation.finish === "function"
})

There are two changes that need to be done in React.

  1. Add the suspend boolean prop to the <CuriProvider>. When suspend is true, the provider will use deferred updates (not yet implemented because the API doesn't exist!) to update the state with the new response/navigation.
<CuriProvider router={router} suspend={true}>
  {({ response }) => {
    const { body:Body } = response;
    return <Body />;
  }}
</CuriProvider>
  1. Render a <FinishNavigation> inside of a <React.Placeholder>. The <FinishNavigation> component will call navigation.finish() for you once it mounts (or updates). By placing it inside of a <React.Placeholder>, we ensure that the componentDidMount()/componentDidUpdate() triggers are not called until any suspense code has loaded.

The placeholder's fallback component also needs to be wrapped in a <FinishNavigation> because when the fallback is displayed, the app is essentially rendering a spinner for the next page.

import { FinishNavigation } from "@curi/react";

const User = ({ response }) => (
  <React.Placeholder
    fallback={
      <FinishNavigation>
        <Spinner />
      </FinishNavigation>
    }
  >
    <FinishNavigation>
      <UserContent id={response.params.id} />
    </FinishNavigation>
  </React.Placeholder>
);

The API here is a little verbose, but a component that combines <React.Placeholder> and <FinishNavigation> should help.

import React from "react";
import { FinishNavigation } from "@curi/react";

const NavigationPlaceholder = ({ children, delayMs, fallback }) => (
  <React.Placeholder
    delayMs={delayMs}
    fallback={<FinishNavigation>{fallback}</FinishNavigation>}
  >
    <FinishNavigation>
      {children}
    </FinishNavigation>
  </React.Placeholder>
);

const User = ({ response }) => (
  <NavigationPlaceholder delayMs={2000} fallback={<Spinner />}>
    <UserContent id={response.params.id} />
  </NavigationPlaceholder>
);

@pshrmn pshrmn force-pushed the suspense branch 2 times, most recently from 3c41b9a to 373dcfd Compare August 28, 2018 19:10
@pshrmn pshrmn force-pushed the suspense branch 4 times, most recently from 075e9a3 to 1aae6c6 Compare September 10, 2018 05:19
@pshrmn pshrmn force-pushed the suspense branch 2 times, most recently from 1c0f4ec to 51ee7c3 Compare October 15, 2018 02:31
@pshrmn pshrmn force-pushed the suspense branch 2 times, most recently from 0a3e6d5 to 15fd71a Compare November 2, 2018 20:07
@pshrmn pshrmn changed the base branch from master to dev January 28, 2019 17:24
@pshrmn pshrmn force-pushed the dev branch 4 times, most recently from 6bb978e to b35c0ed Compare January 31, 2019 22:19
@mfolnovic
Copy link

any idea if you could publish this as a separate alpha?

@pshrmn
Copy link
Owner Author

pshrmn commented May 10, 2019

@mfolnovic I'm getting close to releasing v2, at which point I can get this rebased (or at this point it might actually be easier to just copy things into a new PR) and push out a build.

I haven't been paying much attention to React's Suspense development; are they getting closer to releasing suspense for data or is it still only lazy loading?

@mfolnovic
Copy link

@pshrmn cool, tnx for info - this PR is closest to real support for Suspense (data fetching) in router from what I tried (and I tried react router, reach router, navi). :)

I haven't been paying much attention to React's Suspense development; are they getting closer to releasing suspense for data or is it still only lazy loading?

As far as I know, they aren't any news regarding suspense for data fetching.
It's still planned for ~mid 2019 [1].

[1] https://reactjs.org/blog/2018/11/27/react-16-roadmap.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants