首页 > 解决方案 > 反应菜单切换类型错误(gsap,对象不可扩展)

问题描述

我很难弄清楚我的 Gatsby 应用程序的一些问题(我是 Gatsby 的新手。基本上我正在尝试使用 GSAP 实现打开、关闭菜单功能。我面临的问题是在我的if else条件语句中然后我在打开关闭菜单状态之间切换。

奇怪的是我的if语句 gsap 工作得很好,但是在其他条件下,然后我在其中添加 gsap 函数我得到错误"can't define property "_gsap": Object is not extensible"。因为我是 React 和 GSAP 的新手,所以我不知道我做错了什么?这个错误来自哪里,我该如何解决?

这是我的代码:

菜单.js

import React, { useEffect, useRef } from "react";
import { Link } from "gatsby";
import Navbar from "./Navbar";
import gsap from "gsap";

import {
 Github,
 LinkedIn,
 Instagram,
 Facebook,
 Twitter,
 Close,
} from "../assets/svg/social-icons";

const Menu = ({ menuState, setMenuState }) => {
 // Create varibles of our dom nodes
 let menu = useRef(null);
 let revealMenu = useRef(null);
 let revealMenuBackground = useRef(null);

 useEffect(() => {
   if (menuState) {
     console.log("CLOSE");
     gsap.to([revealMenu, revealMenuBackground], {
       duration: 0.8,
       height: 0,
       ease: "power3.inOut",
       stagger: { amount: 0.07 },
     });

     gsap.to(menu, {
       duration: 1,
       css: { display: "none" },
     });
   } else if (!menuState) {
     console.log("OPEN");
     // ERROR COMES FROM HERE
     gsap.to([revealMenu, revealMenuBackground], {});
   }
 });

 return (
   <>
     {menuState && (
       <div ref={(el) => (menu = el)} className="hamburger-menu">
         <div
           ref={(el) => (revealMenuBackground = el)}
           className="menu-secondary-background-color"
         ></div>
         <div ref={(el) => (revealMenu = el)} className="menu-layer">
           <div className="wrapper">
             <div className="container">
               <div onClick={() => setMenuState(!menuState)} className="close">
                 <Close />
               </div>
             </div>
             <div className="menu-city-background"></div>
             <span className="menu-text">Menu</span>
             <div className="menu-links">
               <Navbar />
             </div>
             <div className="menu-social-icons">
               <IconList />
             </div>

             <button className="btn menu-resume">Resume</button>
           </div>
         </div>
       </div>
     )}
   </>
 );
};

const IconList = () => {
 return (
   <li>
     <a className="icon social-icon" href="#">
       <Github />
     </a>
     <a className="icon social-icon" href="#">
       <Instagram />
     </a>
     <a className="icon social-icon" href="#">
       <LinkedIn />
     </a>
     <a className="icon social-icon" href="#">
       <Facebook />
     </a>
     <a className="icon social-icon" href="#">
       <Twitter />
     </a>
   </li>
 );
};

export default Menu;

标签: reactjsgsaptogglebutton

解决方案


使用 时useRef,您可以使用 访问您的元素(gsap 需要什么)reference.current

在您的情况下,您应该添加.currentmenu,revealMenurevealMenuBackground,否则 gsap 将无法理解您传递的内容。

例子:

gsap.to([revealMenu.current, revealMenuBackground.current], {});

此外,在您返回时,您应该定义您的引用,例如ref={menu},以便该元素的引用附加到由定义的当前引用useRef

最后但并非最不重要的一点是,useEffect您应该将所有内容包装在一个条件中以检查该 ref 是否包含一个值,如下所示:

useEffect(() => {
  if(menu?.current) {
    // Do your animations here
  }
}

这是因为 React 组件生命周期,其中:

  1. 引用被实例化为 null
  2. useEffect运行并且 ref 将为空
  3. 组件呈现 jsx(这是 ref 附加到其元素的地方)
  4. 现在useEffect将包含参考

推荐阅读