"window.innerWidth < 768" 在 Next.js 中使用 Framer Motion

"window.innerWidth < 768" in Next.js with Framer Motion

我想控制动画(Framer Motion)何时可以使用 window.innerWidth 运行,但在 Next.js 中我收到以下错误消息:

ReferenceError: window is not defined

这是我名为 ValuesSection.jsx:

的组件的简化版本
import React, { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import { motion, useAnimation } from "framer-motion";

export default function ValuesSection() {
  const controls = useAnimation();
  const [ref, inView] = useInView();
  const MobileView = {};
  const isMobile = window.innerWidth < 768;
  if (!isMobile) {
    MobileView = {
      visible: { y: 0, scale: 1 },
      hidden: { y: 250, scale: 0 },
    };
  }

  useEffect(() => {
    if (inView) {
      controls.start("visible");
    }
  }, [controls, inView]);

  return (
<>
 <motion.div
  key={value.name}
  ref={ref}
  animate={controls}
  initial="hidden"
  variants={MobileView}
 >Some content</motion.div>
</>

你能帮我理解我做错了什么吗?如果您能为我提供一个工作示例,那将是非常好的,我们将不胜感激。

在 next.js 项目中使用屏幕尺寸的最佳方法是,您可以改用 materiial ui 中的钩子,当屏幕宽度大于或小于定义值时,它表示真或假,在我的我认为它比 window 更好,因为它有很多选项可供您使用,这里是您应该逐步执行的操作

首先安装 material ui 如果您还没有安装

// with npm
npm install @material-ui/core

// with yarn
yarn add @material-ui/core

然后在您的组件中导入并定义它

import { useMediaQuery } from "@material-ui/core";


export default function ValuesSection() {

const IsTabletOrPhone = useMediaQuery("(max-width:1024px)");

现在如果你的屏幕尺寸大于1024px它returnsfalse,否则它returnstrue
所以你可以使用它

  if (!IsTabletOrPhone) {
    MobileView = {
      visible: { y: 0, scale: 1 },
      hidden: { y: 250, scale: 0 },
    };
  }

更新:

可能是因为我给它分配了一个大写字母,你可以尝试将名称更改为 isTabletOrPhone 小写,如果这不起作用尝试将其更改为 let 而不是

let isTabletOrPhone = useMediaQuery("(max-width:1024px)");

在 Next.js 页面在服务器上预呈现。服务器上没有 window。您可以在访问它之前检查 window 是否存在

const isMobile = global.window && window.innerWidth < 768;

请注意,用户可能会旋转 phone 或调整 window 的大小,因此您应该将 resize 事件处理程序添加(并清理)到 useEffect