Turn Page.suppressFirstRenderFlicker and authenticate into React components
- Dominant language
- TypeScript
- Stars
- 14.1k
- Forks
- 803
- PR merge metrics
- No merged PRs in 30d
Description
### What do you want and why?
(Edited from my thread on Discord)
It would be beneficial to convert page options like suppressFirstRenderFlicker and authenticate into React components. Having options as `Page.xxx = x` restricts you to configuring the option upfront and doesn't mesh with how developers expect to compose features in React components.
Benefits:
- no learning curve, React devs are familiar with components already
- config options become props, allowing you to e.g. set the redirectTo path with a dynamic expression at render-time
- you can attach `` or `` anywhere in the component graph, such as in a `` to automatically configure multiple pages
- Components are the de facto unit of composition in React; the more things that are components, the better
- backwards compatible by rendering the components where they appear in the main wrapper now
- main wrapper component stops violating Single Responsibility Principle
- `` being a component means it can be rendered conditionally, which makes it more flexible for devs to use
### Possible implementation(s)
I think it would mostly be a matter of moving the existing logic out of the main wrapper and into separate components, or via `useLayoutEffect()` and `createPortal()` to access the app root and initial paint regardless of where the component sits in the component graph.
SuppressFirstRenderFlicker would probably want to have an assertion when NODE_ENV=development to issue a warning if it gets mounted after the initial render, telling the developer to move it higher up in the component graph.
### Additional context
Comparison:
```tsx
// current
const Layout: BlitzLayout = ({ children }) => {
return
}
// I honestly didn't know these options even worked on layouts,
// and I'm probably not the only one who didn't realize this
Layout.authenticate = {redirectTo: '/login'}
Layout.suppressFirstRenderFlicker = true
```
vs
```tsx
// proposal
const Layout: BlitzLayout = ({ children }) => {
return <>
}
```
cc @flybayer
Contributor guide
Assessment
This issue has not been assessed yet.