React 18迁移至Preact时遇hydrateFn.apply(...) is undefined错误求助
迁移React 18到Preact时next-mdx-remote出现
hydrateFn.apply(...) is undefined错误的解决方案 问题详情
将Web应用从React 18迁移至Preact后,使用next-mdx-remote时触发错误:hydrateFn.apply(...) is undefined
堆栈跟踪
./node_modules/next-mdx-remote/dist/index.js/MDXRemote/Content<@http://localhost:3000/vendors-node_modules_next-mdx-remote_index_js-node_modules_next-mdx-remote_serialize_js.iframe.bundle.js:38494:26 mountMemo@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:45650:19 useMemo@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:46095:16 useMemo@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:61025:21 MDXRemote@http://localhost:3000/vendors-node_modules_next-mdx-remote_index_js-node_modules_next-mdx-remote_serialize_js.iframe.bundle.js:38481:67 renderWithHooks@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:44730:27 mountIndeterminateComponent@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:48494:13 beginWork@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:50007:16 beginWork$1@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:55846:14 performUnitOfWork@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:54980:12 workLoopSync@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:54886:22 renderRootSync@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:54854:7 recoverFromConcurrentError@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:54270:34 performConcurrentWorkOnRoot@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:54170:22 workLoop@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:62407:42 flushWork@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:62380:14 performWorkUntilDeadline@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:62674:21 EventHandlerNonNull*./node_modules/scheduler/cjs/scheduler.development.js/<@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:62712:3 ./node_modules/scheduler/cjs/scheduler.development.js@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:62774:5 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/scheduler/index.js@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:62790:20 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/react-dom/cjs/react-dom.development.js/<@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:28452:36 ./node_modules/react-dom/cjs/react-dom.development.js@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:58287:5 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/react-dom/index.js@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:58364:20 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/react-dom/client.js@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:58302:28 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/@storybook/react-dom-shim/dist/react-18.mjs@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:1318:93 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/@storybook/react/dist/chunk-JWY6Y6NU.mjs@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:1345:102 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/@storybook/react/dist/config.mjs@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:1373:96 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 ./node_modules/@storybook/react/preview.js@http://localhost:3000/vendors-node_modules_storybook_addon-a11y_dist_preview_mjs-node_modules_storybook_addon-essen-d080cc.iframe.bundle.js:1439:93 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 fn@http://localhost:3000/runtime~main.iframe.bundle.js:344:21 getProjectAnnotations@http://localhost:3000/main.iframe.bundle.js:2987:75 ../../node_modules/synchronous-promise/index.js/_runResolutions/<@http://localhost:3000/sb-preview/runtime.js:4:80022 _runResolutions@http://localhost:3000/sb-preview/runtime.js:4:79963 then@http://localhost:3000/sb-preview/runtime.js:4:77505 getProjectAnnotationsOrRenderError@http://localhost:3000/sb-preview/runtime.js:81:13211 initialize@http://localhost:3000/sb-preview/runtime.js:81:12536 ./storybook-config-entry.js@http://localhost:3000/main.iframe.bundle.js:3003:9 __webpack_require__@http://localhost:3000/runtime~main.iframe.bundle.js:28:33 __webpack_exec__@http://localhost:3000/main.iframe.bundle.js:3122:67 @http://localhost:3000/main.iframe.bundle.js:3123:258 __webpack_require__.O@http://localhost:3000/runtime~main.iframe.bundle.js:80:23 @http://localhost:3000/main.iframe.bundle.js:3124:56 webpackJsonpCallback@http://localhost:3000/runtime~main.iframe.bundle.js:1241:46 @http://localhost:3000/main.iframe.bundle.js:1:73
相关依赖版本
"preact": "^10.18.1", "react": "npm:@preact/compat", "react-dom": "npm:@preact/compat", "next-mdx-remote": "4.4.1"
解决方案
- 升级
next-mdx-remote版本:当前4.4.1版本对Preact的hydrate逻辑兼容存在问题,升级到最新稳定版(如4.4.3及以上),新版本修复了Preact环境下的hydrate函数调用异常。 - 确认Preact别名配置:在Next.js的
next.config.js中确保react/react-dom的导入正确指向preact/compat,配置如下:
module.exports = { webpack: (config) => { config.resolve.alias = { ...config.resolve.alias, 'react': 'preact/compat', 'react-dom/test-utils': 'preact/test-utils', 'react-dom': 'preact/compat', }; return config; }, };
- 临时禁用hydrate:如果升级版本后问题仍存在,可以在使用
MDXRemote时关闭服务端hydrate,改用客户端渲染:
import { MDXRemote } from 'next-mdx-remote'; export default function Page({ mdxSource }) { return <MDXRemote {...mdxSource} hydrate={false} />; }
- 修复Storybook配置:从堆栈跟踪可见错误发生在Storybook环境,需在
.storybook/main.js中添加Preact别名配置:
module.exports = { webpackFinal: async (config) => { config.resolve.alias = { ...config.resolve.alias, 'react': 'preact/compat', 'react-dom': 'preact/compat', }; return config; }, };
内容的提问来源于stack exchange,提问作者Jose Miguel Arroyave
相关产品推荐
相关产品推荐

