使用react-data-table-component分页时遇Hydration失败错误求助
问题:React-Data-Table-Component 启用分页后出现 Hydration 失败错误
我使用react-data-table-component创建表格,启用pagination属性后持续报错:Error: Hydration failed because the initial UI does not match what was rendered on the server.,移除pagination属性后错误消失。
使用的基础代码如下:
import Head from 'next/head' import Image from 'next/image' import styles from '../styles/Home.module.css' import DataTable from 'react-data-table-component'; // 简单的展开组件 const ExpandedComponent = ({ data }) => <pre>{JSON.stringify(data, null, 2)}</pre>; const columns = [ { name: '标题', selector: row => row.title, }, { name: '年份', selector: row => row.year, }, ]; const data = [ { id: 1, title: 'Beetlejuice', year: '1988', }, { id: 2, title: 'Ghostbusters', year: '1984', }, { id: 3, title: 'Ghostbusters3', year: '1985', }, { id: 4, title: 'Ghostbusters4', year: '1986', }, ] export default function Home() { return ( <DataTable title="电影列表" columns={columns} data={data} pagination /> ) }
控制台错误信息:
next-dev.js?3515:20 Warning: Expected server HTML to contain a matching <span> in <nav>. at span at O (webpack-internal:///./node_modules/styled-components/dist/styled-components.browser.esm.js:31:19750) at nav at O (webpack-internal:///./node_modules/styled-components/dist/styled-components.browser.esm.js:31:19750) at eval (webpack-internal:///./node_modules/react-data-table-component/dist/index.cjs.js:396:40) at div at Fe (webpack-internal:///./node_modules/styled-components/dist/styled-components.browser.esm.js:31:17299) at eval (webpack-internal:///./node_modules/react-data-table-component/dist/index.cjs.js:396:6011) at Home at MyApp (webpack-internal:///./pages/_app.js:9:11) at PathnameContextProviderAdapter (webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:11) at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:301:63) at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:850:919) at Container (webpack-internal:///./node_modules/next/dist/client/index.js:61:1) at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:171:11) at Root (webpack-internal:///./node_modules/next/dist/client/index.js:346:11) window.console.error @ next-dev.js?3515:20 printWarning @ react-dom.development.js?ac89:86 error @ react-dom.development.js?ac89:60 warnForInsertedHydratedElement @ react-dom.development.js?ac89:10499 didNotFindHydratableInstance @ react-dom.development.js?ac89:11458 warnNonhydratedInstance @ react-dom.development.js?ac89:12385 tryToClaimNextHydratableInstance @ react-dom.development.js?ac89:12534 updateHostComponent @ react-dom.development.js?ac89:19902 beginWork @ react-dom.development.js?ac89:21618 beginWork$1 @ react-dom.development.js?ac89:27426 performUnitOfWork @ react-dom.development.js?ac89:26557 workLoopSync @ react-dom.development.js?ac89:26466 renderRootSync @ react-dom.development.js?ac89:26434 performConcurrentWorkOnRoot @ react-dom.development.js?ac89:25738 workLoop @ scheduler.development.js?bcd2:266 flushWork @ scheduler.development.js?bcd2:239 performWorkUntilDeadline @ scheduler.development.js?bcd2:533 react-dom.development.js?ac89:12507 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server. at throwOnHydrationMismatch (react-dom.development.js?ac89:12507:1) at tryToClaimNextHydratableInstance (react-dom.development.js?ac89:12535:1) at updateHostComponent (react-dom.development.js?ac89:19902:1) at beginWork (react-dom.development.js?ac89:21618:1) at HTMLUnknownElement.callCallback (react-dom.development.js?ac89:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js?ac89:4213:1) at invokeGuardedCallback (react-dom.development.js?ac89:4277:1) at beginWork$1 (react-dom.development.js?ac89:27451:1) at performUnitOfWork (react-dom.development.js?ac89:26557:1) at workLoopSync (react-dom.development.js?ac89:26466:1) at renderRootSync (react-dom.development.js?ac89:26434:1) at performConcurrentWorkOnRoot (react-dom.development.js?ac89:25738:1) at workLoop (scheduler.development.js?bcd2:266:1) at flushWork (scheduler.development.js?bcd2:239:1) at MessagePort.performWorkUntilDeadline (scheduler.development.js?bcd2:533:1) throwOnHydrationMismatch @ react-dom.development.js?ac89:12507 tryToClaimNextHydratableInstance @ react-dom.development.js?ac89:12535 updateHostComponent @ react-dom.development.js?ac89:19902 beginWork @ react-dom.development.js?ac89:21618 callCallback @ react-dom.development.js?ac89:4164 invokeGuardedCallbackDev @ react-dom.development.js?ac89:4213 invokeGuardedCallback @ react-dom.development.js?ac89:4277 beginWork$1 @ react-dom.development.js?ac89:27451 performUnitOfWork @ react-dom.development.js?ac89:26557 workLoopSync @ react-dom.development.js?ac89:26466 renderRootSync @ react-dom.development.js?ac89:26434 performConcurrentWorkOnRoot @ react-dom.development.js?ac89:25738 workLoop @ scheduler.development.js?bcd2:266 flushWork @ scheduler.development.js?bcd2:239 performWorkUntilDeadline @ scheduler.development.js?bcd2:533 next-dev.js?3515:20 Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>. See more info here: https://nextjs.org/docs/messages/react-hydration-error window.console.error @ next-dev.js?3515:20 printWarning @ react-dom.development.js?ac89:86 error @ react-dom.development.js?ac89:60 errorHydratingContainer @ react-dom.development.js?ac89:11473 recoverFromConcurrentError @ react-dom.development.js?ac89:25846 performConcurrentWorkOnRoot @ react-dom.development.js?ac89:25750 workLoop @ scheduler.development.js?bcd2:266 flushWork @ scheduler.development.js?bcd2:239 performWorkUntilDeadline @ scheduler.development.js?bcd2:533 5react-dom.development.js?ac89:12507 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server. at throwOnHydrationMismatch (react-dom.development.js?ac89:12507:1) at tryToClaimNextHydratableInstance (react-dom.development.js?ac89:12535:1) at updateHostComponent (react-dom.development.js?ac89:19902:1) at beginWork (react-dom.development.js?ac89:21618:1) at beginWork$1 (react-dom.development.js?ac89:27426:1) at performUnitOfWork (react-dom.development.js?ac89:26557:1) at workLoopSync (react-dom.development.js?ac89:26466:1) at renderRootSync (react-dom.development.js?ac89:26434:1) at performConcurrentWorkOnRoot (react-dom.development.js?ac89:25738:1) at workLoop (scheduler.development.js?bcd2:266:1) at flushWork (scheduler.development.js?bcd2:239:1) at MessagePort.performWorkUntilDeadline (scheduler.development.js?bcd2:533:1) throwOnHydrationMismatch @ react-dom.development.js?ac89:12507 tryToClaimNextHydratableInstance @ react-dom.development.js?ac89:12535 updateHostComponent @ react-dom.development.js?ac89:19902 beginWork @ react-dom.development.js?ac89:21618 beginWork$1 @ react-dom.development.js?ac89:27426 performUnitOfWork @ react-dom.development.js?ac89:26557 workLoopSync @ react-dom.development.js?ac89:26466 renderRootSync @ react-dom.development.js?ac89:26434 performConcurrentWorkOnRoot @ react-dom.development.js?ac89:25738 workLoop @ scheduler.development.js?bcd2:266 flushWork @ scheduler.development.js?bcd2:239 performWorkUntilDeadline @ scheduler.development.js?bcd2:533 react-dom.development.js?ac89:19849 Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering. at updateHostRoot (react-dom.development.js?ac89:19849:1) at beginWork (react-dom.development.js?ac89:21615:1) at beginWork$1 (react-dom.development.js?ac89:27426:1) at performUnitOfWork (react-dom.development.js?ac89:26557:1) at workLoopSync (react-dom.development.js?ac89:26466:1) at renderRootSync (react-dom.development.js?ac89:26434:1) at recoverFromConcurrentError (react-dom.development.js?ac89:25850:1) at performConcurrentWorkOnRoot (react-dom.development.js?ac89:25750:1) at workLoop (scheduler.development.js?bcd2:266:1) at flushWork (scheduler.development.js?bcd2:239:1) at MessagePort.performWorkUntilDeadline (scheduler.development.js?bcd2:533:1)
解决方案
该问题源于react-data-table-component的分页组件在服务端与客户端渲染时生成的DOM结构不一致,尤其是其依赖的styled-components在服务端渲染时存在样式生成时机不匹配的问题。以下是几种可行的解决方法:
方法1:动态导入组件并禁用服务端渲染
在Next.js中使用dynamic导入DataTable,并关闭服务端渲染,让组件仅在客户端渲染:
import Head from 'next/head' import Image from 'next/image' import styles from '../styles/Home.module.css' import dynamic from 'next/dynamic' // 动态导入,禁用SSR const DataTable = dynamic(() => import('react-data-table-component'), { ssr: false, }) // 简单的展开组件 const ExpandedComponent = ({ data }) => <pre>{JSON.stringify(data, null, 2)}</pre>; const columns = [ { name: '标题', selector: row => row.title, }, { name: '年份', selector: row => row.year, }, ]; const data = [ { id: 1, title: 'Beetlejuice', year: '1988', }, { id: 2, title: 'Ghostbusters', year: '1984', }, { id: 3, title: 'Ghostbusters3', year: '1985', }, { id: 4, title: 'Ghostbusters4', year: '1986', }, ] export default function Home() { return ( <DataTable title="电影列表" columns={columns} data={data} pagination /> ) }
方法2:用Suspense包裹组件
若不想完全禁用SSR,可使用React Suspense包裹DataTable,让客户端等待组件加载完成后再渲染,避免Hydration不匹配:
import Head from 'next/head' import Image from 'next/image' import styles from '../styles/Home.module.css' import DataTable from 'react-data-table-component'; import { Suspense } from 'react'; // 简单的展开组件 const ExpandedComponent = ({ data }) => <pre>{JSON.stringify(data, null, 2)}</pre>; const columns = [ { name: '标题', selector: row => row.title, }, { name: '年份', selector: row => row.year, }, ]; const data = [ { id: 1, title: 'Beetlejuice', year: '1988', }, { id: 2, title: 'Ghostbusters', year: '1984', }, { id: 3, title: 'Ghostbusters3', year: '1985', }, { id: 4, title: 'Ghostbusters4', year: '1986', }, ] export default function Home() { return ( <Suspense fallback={<div>加载中...</div>}> <DataTable title="电影列表" columns={columns} data={data} pagination /> </Suspense> ) }
方法3:配置styled-components服务端渲染支持
若项目使用styled-components,需在Next.js配置文件中开启其服务端渲染支持,确保服务端与客户端样式生成一致:
在next.config.js中添加:
module.exports = { compiler: { styledComponents: true, }, }
内容的提问来源于stack exchange,提问作者yeln
相关产品推荐
相关产品推荐

