我一直在我的函数组件中使用useRef作为类实例变量的替代品,我真的很喜欢它。所以通常它是这样的:
首先声明变量,例如scrollRef
:
const scrollRef = useRef()
然后,将某个引用的值分配给scrollRef.current
:
<ScrollView ref={ref => { scrollRef.current = ref }}>
// (Yeah, I'm doing mostly React Native)
最后,使用 ref:
<TouchableOpacity onPress={() => scrollRef.current.scrollToEnd()} />
这工作正常。但是当我有很多useRef
时,似乎我有两个问题:
-
.current
无处不在 - 在组件之间传递 refs 时,有一些棘手的情况和混乱,当我们不确定是应该直接读取值还是读取
.current
键时。
所以我想知道是否有更好的方法。
我想用let
而不是const
来声明变量,然后直接分配给.current
:
let myRef = useRef().current
然后直接读取和变异myRef
这样做有什么缺点,是否有不起作用的情况?有没有更好的解决方案可以避免到处使用.current
?
我迟到了,甚至不是反应专家。但是,如果您创建一个指向 current
的变量,然后将一个新对象写入该变量,那么您的变量不再指向 ref.current
。保留该链接的唯一办法是修改变量的属性。
useRef().current
用法有一个缺点。让我们看看下面的代码(使用 React v18.1.0(:
import * as React from 'react';
export default function App() {
const [_, forceUpdate] = React.useReducer((x) => x + 1, 0);
const r1 = React.useRef<HTMLDivElement>();
let r2 = React.useRef<HTMLDivElement>().current;
const r3 = React.useRef<string>();
let r4 = React.useRef<string>().current;
React.useEffect(() => {
console.log('[useEffect] r1: ', r1);
console.log('[useEffect] r2: ', r2);
console.log('[useEffect] r3: ', r3);
console.log('[useEffect] r4: ', r4);
});
return (
<div>
<div ref={r1}>r1 test</div>
<div
ref={(ref) => {
r2 = ref;
}}
>
r2 test
</div>
<button
onClick={() => {
r3.current = 'cool';
r4 = 'cool';
console.log('[onClick] r3: ', r3);
console.log('[onClick] r4: ', r4);
forceUpdate();
}}
>
click me
</button>
</div>
);
}
点击按钮后,让我们看看日志:
[onClick] r3: {current: "cool"}
[onClick] r4: cool
[useEffect] r1: {current: {…}}
[useEffect] r2: HTMLDivElement{attributes: {…}, innerHTML: "r2 test", nodeType: 1, tagName: "div"}
[useEffect] r3: {current: "cool"}
[useEffect] r4: undefined
我创建了两个组引用进行测试:r1
和r2
,r3
和r4
。
如您所见,r4
在useEffect
的价值不是我们所期望的。这是一个undefined
,而不是一个'cool'
字符串。r3
的值是正确的。
斯塔克闪电战