facebook / facebook/docusaurus

Feature: Tabs dynamic defaultValue

Abierto
#5,653 0 comentarios 1 reacción 0 asignados Ver en GitHub
difficulty: advanced feature
Lenguaje dominante
TypeScript
Estrellas
66.2k
Forks
10k
Merge medio
1 d 3 h
PR fusionados (30 d)
52

Descripción

## 🚀 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

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.