如何在Remix开发环境中禁用React StrictMode?
如何在Remix开发环境(npm dev)中禁用React StrictMode?
开发环境下Remix会自动用React StrictMode包裹整个应用,这会导致组件加载两次,进而触发重复的第三方服务请求,最终出现429限流错误。如果你的/app/root.tsx里没有手动添加StrictMode,但仍遇到这个问题,可以通过以下两种方法在npm dev时禁用StrictMode:
方法一:通过remix.config.js配置(Remix v2.x 或 v1.15+)
直接在项目根目录的remix.config.js中添加dev.strictMode配置项,设置为false即可:
/** @type {import('@remix-run/dev').AppConfig} */ export default { // 保留原有配置(比如appDirectory、assetsBuildDirectory等) dev: { strictMode: false, }, };
修改后重启npm dev,StrictMode就会被禁用,组件不会再重复加载。
方法二:自定义入口文件(兼容旧版Remix)
如果你的Remix版本不支持上述配置,可以通过自定义entry.client.tsx和entry.server.tsx,结合环境变量手动控制StrictMode的启用:
1. 修改entry.client.tsx
import { RemixBrowser } from "@remix-run/react"; import { startTransition, StrictMode } from "react"; import { hydrateRoot } from "react-dom/client"; const hydrate = () => { startTransition(() => { const rootElement = document.getElementById("root"); if (!rootElement) return; const app = <RemixBrowser />; // 根据环境变量判断是否启用StrictMode const wrappedApp = process.env.NODE_ENV === "development" && !process.env.DISABLE_STRICT_MODE ? <StrictMode>{app}</StrictMode> : app; hydrateRoot(rootElement, wrappedApp); }); }; if (window.requestIdleCallback) { window.requestIdleCallback(hydrate); } else { setTimeout(hydrate, 1); }
2. 修改entry.server.tsx
import { PassThrough } from "node:stream"; import type { AppLoadContext, EntryContext } from "@remix-run/node"; import { createReadableStreamFromReadable } from "@remix-run/node"; import { RemixServer } from "@remix-run/react"; import { isbot } from "isbot"; import { renderToPipeableStream } from "react-dom/server"; import { StrictMode } from "react"; const ABORT_DELAY = 5_000; export default function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext, loadContext: AppLoadContext ) { return isbot(request.headers.get("user-agent") || "") ? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext) : handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext); } function handleBotRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext ) { return new Promise((resolve, reject) => { let shellRendered = false; const { pipe, abort } = renderToPipeableStream( // 环境变量控制StrictMode process.env.NODE_ENV === "development" && !process.env.DISABLE_STRICT_MODE ? <StrictMode><RemixServer context={remixContext} url={request.url} /></StrictMode> : <RemixServer context={remixContext} url={request.url} />, { onAllReady() { shellRendered = true; const body = new PassThrough(); const stream = createReadableStreamFromReadable(body); responseHeaders.set("Content-Type", "text/html"); resolve( new Response(stream, { headers: responseHeaders, status: responseStatusCode, }) ); pipe(body); }, onShellError(error: unknown) { reject(error); }, onError(error: unknown) { responseStatusCode = 500; if (shellRendered) console.error(error); }, } ); setTimeout(abort, ABORT_DELAY); }); } function handleBrowserRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext ) { return new Promise((resolve, reject) => { let shellRendered = false; const { pipe, abort } = renderToPipeableStream( // 环境变量控制StrictMode process.env.NODE_ENV === "development" && !process.env.DISABLE_STRICT_MODE ? <StrictMode><RemixServer context={remixContext} url={request.url} /></StrictMode> : <RemixServer context={remixContext} url={request.url} />, { onShellReady() { shellRendered = true; const body = new PassThrough(); const stream = createReadableStreamFromReadable(body); responseHeaders.set("Content-Type", "text/html"); resolve( new Response(stream, { headers: responseHeaders, status: responseStatusCode, }) ); pipe(body); }, onShellError(error: unknown) { reject(error); }, onError(error: unknown) { responseStatusCode = 500; if (shellRendered) console.error(error); }, } ); setTimeout(abort, ABORT_DELAY); }); }
3. 更新package.json的dev脚本
在scripts中添加环境变量DISABLE_STRICT_MODE=true:
"scripts": { "dev": "DISABLE_STRICT_MODE=true remix dev", // 保留其他脚本(build、start等) }
完成以上修改后,运行npm dev就会自动禁用StrictMode,避免重复请求导致的429错误。
内容的提问来源于stack exchange,提问作者aherve
相关产品推荐
相关产品推荐

