material-ui useMediaQuery在Next.js中与动态组件的配合不佳,

svujldwt  于 5个月前  发布在  其他
关注(0)|答案(5)|浏览(56)

重复问题

  • 我搜索了现有的问题

最新版本

  • 我测试了最新版本

重现步骤 🕹

链接到实时示例:
https://codesandbox.io/p/sandbox/usemediaquery-and-suspense-ipi2y0
步骤:

  1. 导航到 https://ipi2y0-3000.preview.csb.app/example 以重现错误。
  2. 我们还可以通过更新 useLayoutEffecthttps://ipi2y0-3000.preview.csb.app/possible-cause 中的状态来产生相同的错误。
  3. 如果在这种情况下更新 useLayoutEffect 是根本原因,一个可能的修复方法是将这些函数 Package 在 startTransition 中,如 https://ipi2y0-3000.preview.csb.app/possible-fix 所示。

当前行为 😯

当在具有动态导入组件的组件中使用 useMediaQuery 时,Next.js会发出以下错误。

Error: This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.

预期行为 🤔

在使用动态导入组件的钩子时,不应该有任何错误。

上下文 🔦

我正在使用 useMediaQuery 在具有懒加载组件的组件中。

你的环境 🌎

npx @mui/envinfo

Browser: Google Chrome 109

 System:
    OS: Linux 5.15 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
  Binaries:
    Node: 16.17.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 8.15.0 - /usr/local/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    @emotion/react: ^11.10.5 => 11.10.5 
    @emotion/styled: ^11.10.5 => 11.10.5 
    @mui/base:  5.0.0-alpha.114 
    @mui/core-downloads-tracker:  5.11.5 
    @mui/material: ^5.11.5 => 5.11.5 
    @mui/private-theming:  5.11.2 
    @mui/styled-engine:  5.11.0 
    @mui/system:  5.11.5 
    @mui/types:  7.2.3 
    @mui/utils:  5.11.2 
    @types/react: 18.0.26 => 18.0.26 
    react: 18.2.0 => 18.2.0 
    react-dom: 18.2.0 => 18.2.0 
    typescript: 4.9.4 => 4.9.4
4xrmg8kj

4xrmg8kj1#

yjoer,你想提交带有建议修复的PR吗?我们可以尝试使用startTransition并添加一些测试,看看是否一切按预期工作。

svmlkihl

svmlkihl2#

在挖掘一段时间后,我确认这与 useLayoutEffect 无关。由于我正在使用 React 18 并且 useSyncExternalStore 可用,所使用的实现是 useMediaQueryNew 。起初,我打算忽略服务器快照,并在挂载后让客户端重新渲染组件,前提是有不匹配的情况。但似乎 useSyncExternalStore 的工作方式不允许这样做。React 会在悬念边界内的内部树渲染之前重新渲染外部树。沿着这些思路,我认为直接的解决方案是:

  1. 确保客户端和服务器之间的快照匹配。
  2. 如果我们想在具有挂起组件的组件中使用 useMediaQuery ,则禁用 SSR。
  3. 在没有挂起组件的组件中使用 useMediaQuery 。即使有不匹配,这也总是有效的。
58wvjzkj

58wvjzkj3#

我遇到了同样的问题。

sr4lhrrt

sr4lhrrt4#

解决方法

import { useMediaQuery } from '@react-hookz/web';

export function useSidebarFloating() {
  const theme = useTheme();
  return (
    useMediaQuery(theme.breakpoints.down('md').replace(/^@media( ?)/m, '')) ??
    false
  );
}
vm0i2vca

vm0i2vca5#

解决方法:

import { useMediaQuery } from '@react-hookz/web';
export function useSidebarFloating() {
  const theme = useTheme();
  return (
    

useMediaQuery(theme.breakpoints.down('md').replace(/^@media( ?)/m, '')) ??

false


  );
}

这个解决方案很好,但对于 theme.breakpoints.up() 可能不起作用。我认为 mui 在断点处返回了一些额外的字符串。你应该检查一下并使用正则表达式来移除额外的内容。

相关问题