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

React18拆分ApolloProvider组件后ReactDOM渲染报错求助

React 18 抽离ApolloProvider后渲染报错修复方案

问题复现

初始直接在index.js中配置ApolloProvider时,可正常连接Apollo Server,可用代码如下:

import { React } from 'react';
import * as ReactDOM from 'react-dom/client';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import App from './App';
import { createHttpLink } from 'apollo-link-http';

const httpLink = createHttpLink({
    uri: 'http://localhost:5002'
})

const client = new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache()
})

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>,
);

为实现代码解耦,新建ApolloProvider.js文件尝试将Apollo相关配置抽离为独立组件,代码如下:

import React from "react";
import App from "./App";
import { createHttpLink } from 'apollo-link-http';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';

const httpLink = createHttpLink({
    uri: 'http://localhost:5002'
})

const client = new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache()
})

export default (
    <ApolloProvider client = { client } >
        <App/>
    </ApolloProvider>
)

修改index.js引入抽离后的组件执行渲染,代码如下:

import ReactDOM from 'react-dom';
import ApolloProvider from './ApolloProvider';

ReactDOM.render(ApolloProvider, document.getElementById('root'));

运行后触发报错:

ReactDOM.render is no longer supported in React 18. Use createRoot instead.

报错截图

错误原因

  • React 18 已完全废弃旧版ReactDOM.render渲染API,必须从react-dom/client导入createRoot方法完成根节点挂载
  • 抽离组件时命名与官方ApolloProvider组件重名,易引发冲突;且直接硬编码App组件到Provider文件中,并未真正实现解耦
  • 导入ReactDOM的路径错误,旧版react-dom包下不存在适配React 18的渲染方法

正确修复方案

步骤1:优化抽离的Provider组件

修改ApolloProvider.js,封装为标准React组件,通过children接收子元素,避免硬编码App组件,同时规避和官方组件的命名冲突问题:

import React from "react";
import { createHttpLink } from 'apollo-link-http';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';

const httpLink = createHttpLink({
    uri: 'http://localhost:5002'
})

const client = new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache()
})

// 自定义组件名避免和官方ApolloProvider重名
export default function CustomApolloProvider({ children }) {
    return (
        <ApolloProvider client={client}>
            {children}
        </ApolloProvider>
    )
}

步骤2:修正index.js渲染逻辑

使用React 18标准的createRootAPI完成挂载,以JSX标签形式使用抽离的组件:

import * as ReactDOM from 'react-dom/client';
import App from './App';
import CustomApolloProvider from './ApolloProvider';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <CustomApolloProvider>
        <App />
    </CustomApolloProvider>
);

如果不需要保留组件的扩展性,也可以直接在抽离文件中导出写好App的JSX元素,在index.js中直接传入render方法渲染,该写法仅作兼容参考,不推荐在生产环境使用:

// index.js
import * as ReactDOM from 'react-dom/client';
import ApolloApp from './ApolloProvider';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(ApolloApp);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:57:19