facebook / facebook/docusaurus

Feature: Tabs dynamic defaultValue

Ouverte
#5,653 0 commentaires 1 réaction 0 personnes assignées Voir sur GitHub
difficulty: advanced feature
Langage dominant
TypeScript
Étoiles
66.2k
Forks
10k
Merge moyen
1 j 3 h
PR mergées (30 j)
52

Description

## 🚀 Feature

Docusaurus does not have a good API to support dynamic Tabs defaultValue, particularly where the value can only be computed on the browser.

The following code will lead to a SSR/client defaultValue mismatch for MacOs users:

```jsx
const isMacOS =
typeof window !== "undefined" && navigator.platform.startsWith("Mac");


Android content


iOS content

```

The result is that "android" will be used on the server/SSR, and React will try to hydrate with "ios".

On the client, React will have "ios" in comp state, but display "Android" in the DOM.

Even worst: we can't press the unselected "iOS" tab because `setState("ios")` is no-op for React when state already has this value: bug reported by @Simek 3 times on RN website: https://github.com/facebook/react-native-website/issues/2771

Problem visible here (requires macos + empty localstorage/incognito mode): https://deploy-preview-2804--react-native.netlify.app/docs/running-on-device

---

This issue only surfaced recently due to some recent React hydration optimization, by removing a duplicate React rendering that used to "fix" this issue.

![image](https://user-images.githubusercontent.com/749374/136253242-6613b5d4-fe1b-4e65-9585-b7d4c1677187.png)

I'm temporarily restoring the duplicate tabs rendering on hydration in https://github.com/facebook/docusaurus/pull/5652, so that it is fixed, but we need a proper design to solve this problem without any duplicate rendering (or at least avoid this duplicate rendering if the tab is the same on server/client)

### Have you read the [Contributing Guidelines on issues](https://github.com/facebook/docusaurus/blob/main/CONTRIBUTING.md#reporting-new-issues)?

yes

### Has this been requested on [Canny](https://docusaurus.io/feature-requests)?

no

## Motivation

Officially support and document dynamic tabs defaultValue

## API Design

To avoid any potential hydration nasty issues, we must ensure that server/client have the same value during SSR/hydration. The tab should only be updated after React has successfully hydrated.

I'm thinking of something like:

```jsx
const isMacOS = () => navigator.platform.startsWith("Mac");

isBrowser && isMacOS() ? "ios" : "android"}>

Android content


iOS content

```

Also, seeing first android, and then having the UI magically switch to iOS after hydration is a bit weird for the user. As tabs are rendered eagerly by default, we should try to find a way to make the user see the ios tab even before React hydrates (this may not be simple 😅 ). Problem visible here:
- https://deploy-preview-5652--docusaurus-2.netlify.app/tests/pages/tabs-tests
- https://deploy-preview-2739--react-native.netlify.app/docs/running-on-device

## Related links

- 2024 conversion asking for a solution: https://github.com/facebook/docusaurus/discussions/10373

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.