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

在WordPress中集成React Router时遇元素无效及DOM容器问题

在WordPress中正确挂载带React Router的React应用

第一个问题:Element type is invalid(Minified React error #130)

问题场景

原本WordPress里React渲染正常,加了React Router后就报这个错:

react-dom.min.js?ver=18.2.0:10 Error: Minified React error #130; Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

初始代码

index.js:

import HomePageFlightContainer from './HomePageFlightContainer';
import PageFetch from './PageFetch';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const App = () => {
    return (
        <Router >
            <Switch>
               <Route path="/wordpress/search" component={PageFetch} />
               <Route path="/" component={HomePageFlightContainer} />
            </Switch>
        </Router>
    );
};

ReactDOM.render(<App />, document.getElementById('root'));

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React App Setup</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

初始webpack.config.js:

const defaults = require('@wordpress/scripts/config/webpack.config');

module.exports = {
  ...defaults,
  externals: {
    "react": 'React',
    "react-dom": 'ReactDOM',
  },
};

问题原因&解决办法

  1. React Router版本不兼容:如果用的是v6版本,Switch已经被移除,要换成Routes,同时Route的写法也需要调整——原来的component属性要改成element,且组件需用标签形式包裹:
// 先修改导入语句
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

const App = () => {
    return (
        <Router>
            <Routes>
                <Route path="/wordpress/search" element={<PageFetch />} />
                <Route path="/" element={<HomePageFlightContainer />} />
            </Routes>
        </Router>
    );
};
  1. Webpack externals配置不全:原配置仅将react和react-dom设为外部依赖,但react-router-dom未配置。如果WordPress本身未加载react-router-dom的全局变量,要么将其也加入externals,要么直接移除react和react-dom的externals配置,让webpack将所有依赖打包进bundle(更稳妥,避免版本冲突)。

  2. 组件导入错误:检查HomePageFlightContainer和PageFetch的导出方式,如果是命名导出,导入时需添加花括号,比如import { PageFetch } from './PageFetch';如果是默认导出,确保导入语句正确。


第二个问题:Target container is not a DOM element

问题场景

改用index.php作为入口后,出现以下错误:

Target container is not a DOM element.

更新后的代码

index.php:

<!DOCTYPE html>
<html lang="<?php language_attributes(); ?>">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title><?php wp_title(); ?></title>
    <?php wp_head(); ?>
</head>

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="./dist/js/bundle.js"></script>. 
    <?php wp_footer(); ?>
</body>

</html>

更新后的webpack.config.js:

const path = require('path');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const webpackConfig = {
    mode: 'development',
    entry: {
        bundle: path.join(__dirname, 'src', 'index.js')
    },
    output: {
        filename: 'js/[name].js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/'
    },
    module: {
        rules: [
            {
                test: /.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /.(css|scss)$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: {
                    loader: 'file-loader',
                    options: {
                        name: 'wp-content/themes/travel/dist/img/[name].[ext]'
                    }
                }
            }
        ]
    },
    plugins: [
        new BrowserSyncPlugin({
            proxy: {
                target: 'https://localhost'
            },
            files: ['**/*.php'],
            cors: true,
            reloadDelay: 0,
            open: false
        }),
        new MiniCssExtractPlugin({
            filename: 'css/style.[name].css',
        })
    ]
};

if (process.env.NODE_ENV === 'production') {
    webpackConfig.mode = 'production';
}

module.exports = webpackConfig;

问题原因&解决办法

  1. Script路径错误:./dist/js/bundle.js是相对路径,在WordPress主题中需使用绝对路径,建议用WordPress自带函数获取主题路径,避免出错:
// 替换原script标签,注意删除标签后多余的点
<script src="<?php echo get_template_directory_uri(); ?>/dist/js/bundle.js"></script>
  1. JS执行时机过早:如果JS在DOM未加载完成时执行,会找不到#root元素,有两种解决方式:

    • 给script标签添加defer属性,使其等待DOM加载完成后再执行:
      <script src="<?php echo get_template_directory_uri(); ?>/dist/js/bundle.js" defer></script>
      
    • 在React代码中监听DOMContentLoaded事件,等DOM准备好后再渲染:
      // 替换原ReactDOM.render语句
      document.addEventListener('DOMContentLoaded', () => {
          ReactDOM.render(<App />, document.getElementById('root'));
      });
      
      若使用React 18,建议改用新的createRoot写法:
      import { createRoot } from 'react-dom/client';
      
      document.addEventListener('DOMContentLoaded', () => {
          const root = createRoot(document.getElementById('root'));
          root.render(<App />);
      });
      
  2. Webpack publicPath配置错误:当前publicPath: '/',若主题位于子目录(如/wp-content/themes/travel/),需将publicPath调整为对应路径:

publicPath: '/wp-content/themes/travel/dist/'

总结:WordPress挂载React App的正确姿势

  1. 对齐React Router版本:v6版本需用Routes替代Switch,element替代component,避免使用旧语法。
  2. Webpack适配WordPress:
    • 要么将所有依赖打包(移除不必要的externals),要么确保externals中的依赖WordPress均可提供。
    • 配置正确的output路径和publicPath,匹配主题目录结构。
  3. 使用WordPress模板文件:以index.php作为主题入口,用get_template_directory_uri()获取静态资源路径,避免硬编码相对路径。
  4. 确保DOM加载完成后渲染:通过defer属性或DOMContentLoaded事件保证JS执行时机正确。
  5. 检查组件导入导出:确认组件的导出和导入方式匹配,避免因导入错误导致组件未定义。

内容的提问来源于stack exchange,提问作者user1207289

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:02:05