【发布时间】:2021-08-19 12:20:29
【问题描述】:
提供实时示例here
我正在尝试制作一个基本布局,在该布局中,在手机上仅显示最新帖子。在桌面上,左栏应该是帖子,右栏应该是热门类别和最受欢迎的帖子。
这是布局:
const IndexLayout: React.FC<IndexLayoutProps> = ({}) => {
const cols = useScreenType()
return cols === '2-cols' ? (
<div className="w-full flex justify-between items-start">
<ListPosts data-comp="ListPosts" className="w-4/6" />
<div className="sticky ml-12 w-2/6 flex flex-col">
<TopCategories data-comp="TopCategories" className="w-full" />
<PopularPosts data-comp="PopularPosts" className="mt-4" />
</div>
</div>
) : (
<ListPosts data-comp="ListPosts" className="w-full" />
)
}
这是useScreenType 钩子:
import { useMediaQuery } from 'react-responsive'
export const useScreenType = () => {
const is2Cols = useMediaQuery({ minWidth: 1300 })
const is1Cols = useMediaQuery({ minWidth: 800 })
if (is2Cols) {
return '2-cols'
}
if (is1Cols) {
return '1-cols'
}
return 'fullscreen'
}
我不断收到此错误:
Warning: Expected server HTML to contain a matching <div> in <div>.
div
ListPosts@webpack-internal:///./components/posts/ListPosts.tsx:31:19
div
IndexLayout@webpack-internal:///./components/layout/IndexLayout.tsx:28:149
div
Index@webpack-internal:///./pages/index.tsx:24:149
ApolloProvider@webpack-internal:///./node_modules/@apollo/client/react/context/ApolloProvider.js:13:18
s@webpack-internal:///./node_modules/next-apollo/dist/index.es.js:26:1911
div
div
MyApp@webpack-internal:///./pages/_app.tsx:37:19
ErrorBoundary@webpack-internal:///./node_modules/@next/react-dev-overlay/lib/internal/ErrorBoundary.js:23:47
ReactDevOverlay@webpack-internal:///./node_modules/@next/react-dev-overlay/lib/internal/ReactDevOverlay.js:73:20
Container@webpack-internal:///./node_modules/next/dist/client/index.js:155:20
AppContainer@webpack-internal:///./node_modules/next/dist/client/index.js:643:18
Root@webpack-internal:///./node_modules/next/dist/client/index.js:779:19
现在我认为问题是由于useScreenType 钩子无法获得宽度,因为window 未在服务器上定义。但是我该如何解决这个问题?不仅我得到一个错误,而且我的 HTML 呈现奇怪。
最终的渲染结果是这样的(当它渲染为“2-cols”时):
<div class="flex flex-col justify-start items-start w-full">
<div class="mt-6 w-full"></div>
<div class="mt-4 flex items-center cursor-pointer transform transition hover:scale-105 text-sm">
<div class="w-full p-6 rounded-lg flex flex-col dark:bg-gray-800 shadow-md"></div>
<div class="mt-4 p-6 rounded-lg flex flex-col dark:bg-gray-800 shadow-md"></div>
</div>
</div>
注意:我使用的是 Next.js v10.2.0
代码可以在GitHub找到
【问题讨论】:
-
如您所见,您无法访问服务器上的窗口对象,因此如果您想基于窗口对象进行服务器渲染 - 您必须对这些值进行硬编码
-
我不确定这是否真的与缺少对
window对象的访问有关,您可能会得到一个实际错误,而不是像现在这样的警告。您可以尝试查看 SSR example 的 react-responsive,看看这是否是无效标记的原因。 -
很可能是由于缺少窗口对象的错误被处理并使用了某种回退,这给我们留下了警告。
标签: javascript css reactjs next.js tailwind-css