我在Next.js 13中编写了一个应用程序,我使用framer-motion来制作动画。它由一个页面组成,分为几个屏幕,导航通过滚动到它们的部分ID来进行。我使用旧的pages
目录。
其中一个屏幕上的动画使元素在滚动视图时从侧面滑入。在大屏幕上有一个侧边栏,但在移动的上是隐藏的。因此,在大屏幕上,我必须为元素设置一个不同的初始X位置,向右偏移,否则它们会隐藏在侧边栏下面,框架的whenInView
不会触发。
我用这些代码来解决这个问题:
1.一个实用程序函数,它 Package 浏览器的matchMedia
函数,以提供css文件之外的屏幕信息:
export const isMobile = (): boolean => {
if (typeof window === 'undefined') return false;
const query = '(min-width: 320px) and (max-width: 767.98px)';
const match = window.matchMedia(query);
return match.matches;
}
1.元素初始X位置的不同值,例如:
<motion.h1
initial={{ x: isMobile() ? '93vw' : '86vw' }}
whileInView={{ x: 0 }}
transition={{ duration: 0.75, type: 'spring' }}
viewport={{ once: true }}
className={classes.element}
>
Example content
</motion.h1>
1.在所有具有动态初始值的屏幕上,我添加了:
'use client';
问题是我每次刷新都会得到水合错误。
一个三个三个一个
这个问题看起来很明显,但是我不确定如何解决它。我认为'use client'
应该将这个组件排除在服务器渲染之外。或者它只在新的app
目录中工作吗?另外,你认为在useEffect
钩子中设置初始值可以解决这个问题吗?
1条答案
按热度按时间owfi6suc1#
所以,我自己设法解决了这个问题。显然,framer-motion在处理风格等 prop 时足够智能,可以区分客户端和服务器,但在应用的另一部分,我有一个基于
isMobile()
函数的完整条件渲染。它在服务器上解析为false,因为window
未定义,但在客户端上,当在响应模式下使用Chrome dev-tools时,它将为true。因此,这段代码将破坏整个过程,尽管错误是关于其他方面的:
我通过创建一个客户端专用的 Package 器组件来解决这个问题:
希望这对某人有帮助!