You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:59:50