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

Add SSR support #4

Merged
merged 3 commits into from
Mar 23, 2021
Merged

Add SSR support #4

merged 3 commits into from
Mar 23, 2021

Conversation

KittyGiraudel
Copy link
Owner

@KittyGiraudel KittyGiraudel commented Nov 25, 2020

The library works like this: there is an outer context (issued via the FootnotesProvider component). Then every footnote reference being rendered within that context (with the FootnoteRef component) is tracked, in the correct order. From this collection of references can be automatically generated the actual footnotes (the Footnotes component), at the bottom of the page. See the example for more details.

Current problem

In the current version, the footnote references register themselves within the context when mounting:

React.useEffect(() => register(footnote), [register, footnote])

The problem is that it of course doesn’t work with server-side rendering because React.useEffect() does not fire on the server. As a result, the footnote references are being rendered correctly, but they don’t link to anything because no footnotes are effectively recorded in the context.

Suggested solution

This pull-request replaces the state provided through the context with a React ref so it works on the server. So instead of having a footnotes array in the local state and passing it down (and its setter) to the FootnotesContext context, the FootnotesProvider initialises an empty map in a React ref, and passes that ref down.

🤔 Now what I’m not sure about is whether having this ref being mutated in the render method of every footnote reference is a good idea. Basically if they don’t find themselves already in the array, they push themselves in it. It feels a little shady having to do that in the render method.

I’m open to suggestions. :)


The current (state) implementation can be played with here: https://codesandbox.io/s/footnotes-v34hm
The new (ref) implementation can be played with here: https://codesandbox.io/s/footnotes-forked-e3t4f

@diondiondion
Copy link

Haven't looked into it too deeply, but it sounds like this may be a good use case for the upcoming React.useMutableSource hook (which is only available in the experimental branch of React atm). Could also check out this article and library by Travis Arnold for inspiration, though I don't think the current experimental API supports SSR, either.

@KittyGiraudel KittyGiraudel force-pushed the ssr-support branch 3 times, most recently from 9eed553 to ba7eb12 Compare March 21, 2021 10:48
@KittyGiraudel
Copy link
Owner Author

KittyGiraudel commented Mar 21, 2021

I’m thinking using a Map in the ref could also be a good idea since every occurrence can only happen once by definition and saves us from traversing the whole array in every render.

That doesn’t solve my concerns around aggressively mutating a ref in the render method of every footnote reference though.

@KittyGiraudel KittyGiraudel force-pushed the ssr-support branch 4 times, most recently from 58d80ff to 3ca6477 Compare March 23, 2021 12:07
@KittyGiraudel KittyGiraudel force-pushed the ssr-support branch 2 times, most recently from 4388496 to f16ecf2 Compare March 23, 2021 12:11
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