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

React 18初始化与ApolloProvider组件适配问题求助

React 18 + Apollo Client 初始化问题解决指南

问题概述

按官方指南初始化React 18 + Apollo Client项目时,先后遇到两个核心错误:

  1. 初始使用document.getElementById('app')时,报错:Error: createRoot(...): Target container is not a DOM element.
  2. 改为document.getElementById('root')后,出现useQuery相关错误:TypeError: Cannot read properties of null (reading 'useContext')

原代码片段

index.js

import { createRoot } from 'react-dom/client';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import App from './App';

// Initialize Apollo Client
const client = new ApolloClient({
  uri: 'http://localhost:5000/graphql',
  cache: new InMemoryCache()
});

// I have also tried with document.getElementById('root') 
// which exists at the public/index.html yet it also fails
const container = document.getElementById('app');
console.log("container: "+container);
const root = createRoot(container); 

root.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
);

App组件

import React from 'react';
import ECGGraph from './ECGGraph';

function App() {
  return (
    <div className="App" id="App">
      <h1>ECG Data of Alice Johnson</h1>
      <ECGGraph />
    </div>
  );
}

export default App;

解决方案

1. 修复容器DOM元素不存在问题

  • 匹配根容器ID:React项目默认根容器的ID是root(定义在public/index.html中),你代码里的id="App"是组件内部元素,并非React挂载的根容器,必须用document.getElementById('root')获取正确容器。
  • 确保DOM加载完成后执行初始化:如果脚本放在head标签中,DOM未渲染完成会导致获取不到元素。可以把脚本移到body标签末尾,或者用DOM加载事件包裹初始化逻辑:
document.addEventListener('DOMContentLoaded', () => {
  const container = document.getElementById('root');
  const root = createRoot(container); 
  root.render(
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );
});

2. 修复useContext空值错误

  • 升级Apollo Client版本:旧版本@apollo/client不兼容React 18,执行npm install @apollo/client@latest升级到3.7+版本(该版本已完全适配React 18并发特性)。
  • 规范useQuery调用范围:检查ECGGraph组件,确保useQuery仅在被ApolloProvider包裹的组件内部调用,禁止在组件外部、未被包裹的组件或非React环境中使用。
  • 修正render语法:React 18的createRoot().render()不需要第二个参数,移除原代码中render方法末尾的多余逗号。

修正后的index.js代码

import { createRoot } from 'react-dom/client';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import App from './App';

const client = new ApolloClient({
  uri: 'http://localhost:5000/graphql',
  cache: new InMemoryCache()
});

// 确保DOM加载完成后再初始化React应用
document.addEventListener('DOMContentLoaded', () => {
  const container = document.getElementById('root');
  const root = createRoot(container);
  
  root.render(
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );
});

内容的提问来源于stack exchange,提问作者Victor Polo De Gyves Montero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:15:06