React18中ReactDOM.render替换DOM为JSX的控制台错误消除方法
在React 18 + Next.js环境下消除FullCalendar自定义图标ReactDOM.render的控制台错误
React 18废弃了ReactDOM.render,直接调用会触发控制台警告,结合你使用FullCalendar 5.11.2无法直接传入JSX图标的场景,提供两个可行方案:
方案一:用ReactDOM.createPortal替代(推荐)
createPortal是React官方支持的跨DOM节点渲染方式,完全符合React 18规范,不会触发警告,还能保留组件的生命周期特性。
实现步骤:
- 先在FullCalendar的头部按钮配置中,生成带唯一ID的空元素(用来挂载自定义图标):
<FullCalendar headerToolbar={{ left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek' }} // 给需要替换的按钮设置带ID的空span buttonText={{ prev: '<span id="fc-prev-icon"></span>', next: '<span id="fc-next-icon"></span>' }} // 其他FullCalendar配置... />
- 在组件中使用
createPortal将自定义图标挂载到目标元素:
import { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; import FullCalendar from '@fullcalendar/react'; import AnyIconIWantToUse from './YourIconComponent'; const CustomCalendar = () => { const [prevIconTarget, setPrevIconTarget] = useState(null); const [nextIconTarget, setNextIconTarget] = useState(null); // 监听FullCalendar生成的按钮元素是否存在 useEffect(() => { const checkElements = setInterval(() => { const prevElem = document.querySelector('#fc-prev-icon'); const nextElem = document.querySelector('#fc-next-icon'); if (prevElem) setPrevIconTarget(prevElem); if (nextElem) setNextIconTarget(nextElem); if (prevElem && nextElem) clearInterval(checkElements); }, 100); return () => clearInterval(checkElements); }, []); return ( <> <FullCalendar {/* 上述配置 */} /> {/* 用Portal渲染自定义图标 */} {prevIconTarget && createPortal(<AnyIconIWantToUse />, prevIconTarget)} {nextIconTarget && createPortal(<AnyIconIWantToUse />, nextIconTarget)} </> ); }; export default CustomCalendar;
方案二:屏蔽特定控制台警告(权宜之计)
如果暂时不想调整渲染方式,可以针对性屏蔽React 18关于ReactDOM.render的警告,但不推荐长期使用,因为可能会漏掉其他重要错误信息。
在Next.js的_app.js(或_app.tsx)中添加以下代码:
import '../styles/globals.css'; import { useEffect } from 'react'; function MyApp({ Component, pageProps }) { useEffect(() => { // 保存原始console.error方法 const originalError = console.error; console.error = (...args) => { // 过滤ReactDOM.render的警告 if (typeof args[0] === 'string' && args[0].includes('ReactDOM.render is no longer supported in React 18')) { return; } // 其他错误正常输出 originalError(...args); }; return () => { // 组件卸载时恢复原始方法 console.error = originalError; }; }, []); return <Component {...pageProps} />; } export default MyApp;
内容的提问来源于stack exchange,提问作者HYAR7E
相关产品推荐
相关产品推荐

