我不确定如何用较模糊的方式表述问题,但这是关于按值传递和按引用传递的案例。还有钩子。
我正在使用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>
)}
这会引发“ 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>
)}
有人可以向我解释这里发生了什么,甚至扔一个男孩到已经解释过的地方的链接吗?我确定某种形式的Dan字符已在某处写过,但我不确定该如何使用Google。谢谢!
答案 0 :(得分:2)
在第一个示例中,您没有使用ref
,而是通过navbar
回调重新分配ref
,因此navbar
是DOM元素。
与
相同let navbar = null;
return <div ref={node => (navbar = node)} />
在第二个示例中,您使用的ref
对象是具有current
属性的对象,该属性包含DOM元素
const navbar = useRef(null)
return <div ref={navbar} />
导航栏现在为
{ current: the DOM element }
因此,您要将对象传递到myTween.to()
而不是navbar.current
内的DOM元素
现在在第二个示例gsap
中,尝试扩展ref
对象本身而不是DOM元素。
为什么会出现TypeError:无法添加属性_gsap,对象不可扩展?
如果您查看useRef
的源代码,则会在第891
行看到
if (__DEV__) {
Object.seal(ref);
}
React正在密封ref
对象,而当我们尝试使用JavaScript
扩展对象时,Object.defineProperty()
会抛出错误,这很可能是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>
)
}