将 useRef 钩子传递给 ref 属性的正确方法



我不确定如何不那么模糊地表述这个问题,但它是关于反应中的按值传递按引用传递的情况。和钩子。

我正在使用 gsap 对div 滑入和滑出进行动画处理是这方面的上下文,但我猜 ref 的用途并不重要。


所以,这工作正常,即使按照我的理解,这是一种更典型的类组件传递 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>
)}

这引发了"类型错误:无法添加属性_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>
)}

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

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

它与

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

在第二个示例中,您将使用ref对象,该对象是具有保存 DOM 元素的current属性的对象

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

导航栏现在是

{ current: the DOM element }

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

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

为什么我们得到类型错误:无法添加属性_gsap,对象不可扩展'?

如果您查看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>
)
}

相关内容

  • 没有找到相关文章

最新更新