FirebaseExtended / FirebaseExtended/reactfire

example/: kitchen-sink demo cannot be installed, and its Suspense path cannot run

未关闭
#784 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
TypeScript
星标
3.6k
派生
403
平均合并
14 小时 53 分钟
30 天内合并 PR
5

描述

Two pre-existing defects in `example/`, both surfaced by @armando-navarro while reviewing #781 and both verified against `main`. Neither was caused by that PR and neither was fixed by it, so they are filed here rather than left in a review thread on a merged PR.

They are filed together because the fix for the second requires the first: there is no way to check that the Suspense path runs without being able to install the demo.

## 1. The demo cannot be installed as checked out

`example/package.json` depends on:

```json
"reactfire": "file:../reactfire-4.0.1.tgz"
```

That tarball is not in the repository, so `npm install` inside `example/` fails from a clean checkout. Whatever produced it was never committed and no script regenerates it.

Worth deciding rather than patching blindly: the fix could be a `file:..` reference to the workspace, a documented `npm pack` step, or a published version range. They differ in whether the demo is meant to exercise the local working tree or the last release.

## 2. The Suspense path cannot run, on either the old instructions or the new ones

`example/index.tsx` ships a commented-out Suspense variant. #781 corrected the comment to say the path does not run as checked in, which is accurate, but the underlying reason is worth recording.

`example/package.json` pins the runtime to React 17 while the types are already on 18:

```json
"react": "^17.0.0",
"react-dom": "^17.0.0",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"typescript": "^4.7.4"
```

That skew produces two distinct failures.

- **`example/index.tsx:45`**, the commented `ReactDOM.createRoot(rootElement)`. On react-dom 17 this is `undefined` at runtime, and under `@types/react-dom@18` it is also a type error, because `createRoot` is declared in `client.d.ts` and not on the root entry. The example's `build` is `tsc && vite build`, so uncommenting it breaks the build as well as the app.
- **`example/withSuspense/Firestore.tsx:2`**, which imports `useTransition` (used at `:87`). This one **type-checks cleanly** because `@types/react` is already 18, and fails only at runtime on React 17. It is the more dangerous of the two for exactly that reason.

Those are the only React 18 APIs anywhere under `example/`, which bounds the work:

```
example/index.tsx:45: // ReactDOM.createRoot(rootElement).render(
example/withSuspense/Firestore.tsx:2: import { useState, useTransition } from 'react';
example/withSuspense/Firestore.tsx:87: const [isPending, startTransition] = useTransition();
```

**The instructions that #781 replaced did not work either.** Verified on `react@experimental`: `createRoot`, `unstable_createRoot` and `render` are all undefined on the root `react-dom` entry. So this is long-standing, and #781 regressed nothing.

## What the fix involves

1. Bump `react` and `react-dom` to 18 in `example/package.json`, **and the lockfile**.
2. Import `createRoot` from **`react-dom/client`**, not the root entry. It is not on the root entry under `@types/react-dom@18` either, so the currently commented specifier would still be wrong after the bump.
3. Word the comment as **replacing** the existing `ReactDOM.render` call, not uncommenting alongside it. Leaving both produces React 18's `You are calling ReactDOMClient.createRoot() on a container that was previously passed to ReactDOM.render()` warning.
4. Rename `ConcurrentModeApp` / `NonConcurrentModeApp`. "Concurrent mode" has not been the name for this since React 18 shipped, and #781 removed that framing from the surrounding prose but deliberately left the identifiers, since renaming them is not a comments-only change.

#781 also deliberately left the commented `ReactDOM.createRoot` specifier uncorrected. Fixing it in isolation would make the block look runnable, which is the opposite of what the caveat it sits under is for. It should be corrected as part of the bump, not before.

## Not a ReactFire bug

Worth stating explicitly so this is not mistaken for a library problem: **ReactFire itself works fine on React 17.** @armando-navarro ran `useObservable` with `suspense: true` under the legacy render path and it suspends, resolves and keeps updating. The React 18 requirement belongs to the demo, not to the library.

Refs #781.

贡献指南

打开贡献指南

调研方向

从 example/package.json 及其 lockfile 开始,然后检查 example/index.tsx:45 和 example/withSuspense/Firestore.tsx:2,87。首先在 example/ 中进行一次干净安装,并确定 demo 应使用 workspace、生成的 tarball 还是已发布的版本;当依赖项安装成功,并且 Suspense 路径能够构建和运行而不出现所述的 React 17/18 失败时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
react, typescript
领域
build-system, frontend
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
55/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。