FormidableLabs / react-ssr-prepass

A custom partial React SSR renderer for prefetching and suspense
MIT License
592 stars 26 forks source link

Add support for React 17's React.lazy changes, Error Boundaries, and refactor render loop #61

Closed kitten closed 3 years ago

kitten commented 4 years ago

Resolve #22 Resolve #62

The main change that's interestung here is that error boundaries are supported with this PR. It adds a stack that tracks error boundaries as it walks around the element tree and can return to the next highest one if a component errors out while rendering (whether that's on purpose or not) or if a thrown promise as part of suspense rejects.

This allows graceful error recovery even using react-ssr-prepass, which may be important for home-grown fetching libraries that use suspense, or if suspense APIs are used inside the error boundary's fallback.

This PR also upgrades to React 17, which required the React.lazy API to be updated to a new structure.

Furthermore the render loop has been simplified a little, which also affects how ReactCurrentDispatcher is being set, which requires more thorough testing in environments like Next.js.

I've also decided to remove the dependency on object-is and instead just include React's polyfill, and to vendor the react-is symbols/codes as they're meant to remain stable and aren't expected to change often.

As a follow-up to this PR we may want to add support for more of React's new element types.

Edit: it's probably also worth mentioning that renderToString and renderToStaticMarkup don't support error boundaries, just like they don't support suspense. The latter is likely to be added in some form (react-lightyear for instance does add support for Suspense) however for error boundaries a stream could never "go back in time" and has to assume that rendering will always succeed. Adding support for error boundaries can however still be useful, since it means that react-ssr-prepass can hopefully remain useful for other use-cases.