Kie*_*ran 20 javascript typescript reactjs react-hooks
我正在使用此配方useHover()中定义的反应钩子。该钩子返回 a和一个布尔值,指示用户当前是否将鼠标悬停在 this 标识的元素上。它可以像这样使用...refref
function App() {
const [hoverRef, isHovered] = useHover();
return (
<div ref={hoverRef}>
{isHovered ? 'Hovering' : 'Not Hovering'}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
现在假设我想使用另一个(假设的)钩子,useDrag它返回 aref和一个布尔值,指示用户是否在页面周围拖动当前元素。我想在与以前相同的元素上使用它,就像这样......
function App() {
const [hoverRef, isHovered] = useHover();
const [dragRef, isDragging] = useDrag();
return (
<div ref={[hoverRef, dragRef]}>
{isHovered ? 'Hovering' : 'Not Hovering'}
{isDragging ? 'Dragging' : 'Not Dragging'}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
这是行不通的,因为refprop 只能接受单个引用对象,而不是像上面示例中那样的列表。
我该如何解决这个问题,以便我可以在同一个元素上使用多个这样的钩子?我找到了一个看起来可能是我正在寻找的包,但我不确定是否缺少某些东西。
小智 34
下面记录了一种简单的方法。
注意:ref元素上的属性采用一个函数,并且稍后在可用时使用元素或节点调用该函数。
function App() {
const myRef = useRef(null);
return (
<div ref={myRef}>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
因此,myRef上面是一个具有定义的函数
function(element){
// something done here
}
Run Code Online (Sandbox Code Playgroud)
所以一个简单的解决方案如下所示
function App() {
const myRef = useRef(null);
const anotherRef = useRef(null);
return (
<div ref={(el)=> {myRef(el); anotherRef(el);}}>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*imo 22
React ref 实际上只不过是一些可变数据的容器,存储为属性current。有关更多详细信息,请参阅React 文档。
{
current: ... // my ref content
}
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,您应该能够手动解决这个问题:
function App() {
const myRef = useRef(null);
const [hoverRef, isHovered] = useHover();
const [dragRef, isDragging] = useDrag();
useEffect(function() {
hoverRef.current = myRef.current;
dragRef.current = myRef.current;
}, [myRef.current]);
return (
<div ref={myRef}>
{isHovered ? 'Hovering' : 'Not Hovering'}
{isDragging ? 'Dragging' : 'Not Dragging'}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
Rom*_*n86 12
我使用 TypeScript,它不允许轻松分配.current使用useRef或转发的引用创建的引用(因为它也可以是一个RefCallback)。因此,我创建了一个函数,可以巧妙地将所有给定的引用合并为一个RefCallback,以便干净/简单地使用。看一下这个。对我来说效果很好。
import { type MutableRefObject, type RefCallback } from 'react';
type MutableRefList<T> = Array<RefCallback<T> | MutableRefObject<T> | undefined | null>;
export function mergeRefs<T>(...refs: MutableRefList<T>): RefCallback<T> {
return (val: T) => {
setRef(val, ...refs);
};
}
export function setRef<T>(val: T, ...refs: MutableRefList<T>): void {
refs.forEach((ref) => {
if (typeof ref === 'function') {
ref(val);
} else if (ref != null) {
ref.current = val;
}
});
}
Run Code Online (Sandbox Code Playgroud)
interface Props {
// I pass it as a prop, you may use forwardRef - also supported by mergeRefs
inputRef?: Ref<HTMLInputElement>;
}
export function Input({
inputRef,
}: Props): ReactElement {
// some local ref
const privateRef = useRef<HTMLInputElement>(null);
return (
<input
type="text"
ref={mergeRefs(inputRef, privateRef)}
// ... your other stuff
/>
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38768 次 |
| 最近记录: |