【问题标题】:Correct way to pass useRef hook to ref property将 useRef 钩子传递给 ref 属性的正确方法
【发布时间】:2019-12-23 02:23:58
【问题描述】:

我不确定如何更模糊地表述这个问题,但它是关于反应中的 pass-by-valuepass-by-reference 案例。还有 Hooks。

我正在使用 gsap 为 div 滑入和滑出设置动画,这是它的上下文,但我猜测 ref 的用途并不重要。 p>


所以,这很好用,即使这是我理解的传递 ref 的更典型的类组件方式:

const RootNavigation = () => {
var navbar = useRef();

const myTween = new TimelineLite({ paused: true });    
const animate = () => {
    myTween.to(navbar, 0.07, { x: "100" }).play();
  };

return(
     <div className="nav-main" ref={div => (navbar = div)}>   // <<<<<<<<<<   pass as a callback
     ...
    </div>
    )}

这会引发“TypeError:无法添加属性 _gsap,对象不可扩展”错误,尽管 React Hooks 指南会让我这样做:

const RootNavigation = () => {
var navbar = useRef();

const myTween = new TimelineLite({ paused: true });    
const animate = () => {
    myTween.to(navbar, 0.07, { x: "100" }).play();
  };

return(
     <div className="nav-main" ref={navbar}>          //<<<<<<<<<<<<<  not passing a callback
     ...
    </div>
    )}

有人可以向我解释一下这里发生了什么,或者甚至可以给一个男孩一个链接到已经解释过的地方吗?我确定某种丹角色在某处写过它,我只是不确定要谷歌什么。谢谢!

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    在第一个示例中,您没有使用ref,而是通过ref 回调重新分配navbar,因此navbar 是DOM 元素。

    一样
    let navbar = null;
    
    return <div ref={node => (navbar = node)} />
    

    在第二个示例中,您使用的是 ref object,它是一个带有 current 属性的对象,其中包含 DOM 元素

    const navbar = useRef(null)
    
    return <div ref={navbar} />
    

    现在是导航栏

    { current: the DOM element }
    

    因此,您将对象传递给 myTween.to(),而不是 navbar.current 中的 DOM 元素

    现在在第二个示例中,gsap 试图扩展 ref 对象本身,而不是 DOM 元素。

    为什么会出现 TypeError: Cannot add property _gsap, object is not extensible`?

    如果你查看useRef的源代码你会看到891在线

    if (__DEV__) {
      Object.seal(ref);
    }
    

    React 正在密封 ref 对象,当我们尝试使用 Object.defineProperty() 扩展它时,JavaScript 会抛出错误,这可能是 gsap 正在做的事情。

    使用ref 的解决方案是将ref.current 传递给tween.to()

    const RootNavigation = () => {
      const navbar = useRef()
    
      const myTween = new TimelineLite({ paused: true });   
    
      const animate = () => {
        myTween.to(navbar.current, 0.07, { x: "100" }).play()
      }
    
      return (
        <div className="nav-main" ref={navbar}>
          ...
        </div>
      )
    }
    

    【讨论】:

      猜你喜欢
      • 2016-12-16
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 2019-10-01
      • 2021-06-29
      • 2019-07-26
      • 2013-05-18
      • 2021-12-07
      相关资源
      最近更新 更多