简体   繁体   中英

Using multiple refs on a single React element

I'm using the useHover() react hook defined in this recipe . The hook returns a ref and a boolean indicating whether the user is currently hovering over element identified by this ref . It can be used like this...

function App() {
  const [hoverRef, isHovered] = useHover();

  return (
    <div ref={hoverRef}>
      {isHovered ? 'Hovering' : 'Not Hovering'}
    </div>
  );
}

Now let's say that I want to use another (hypothetical) hook called useDrag which returns a ref and a boolean indicating whether the user is dragging the current element around the page. I want to use this on the same element as before like this...

function App() {
  const [hoverRef, isHovered] = useHover();
  const [dragRef, isDragging] = useDrag();

  return (
    <div ref={[hoverRef, dragRef]}>
      {isHovered ? 'Hovering' : 'Not Hovering'}
      {isDragging ? 'Dragging' : 'Not Dragging'}
    </div>
  );
}

This won't work because the ref prop can only accept a single reference object, not a list like in the example above.

How can I approach this problem so I can use multiple hooks like this on the same element? I found a package that looks like it might be what I'm looking for, but I'm not sure if I'm missing something.

A React ref is really nothing but a container for some mutable data, stored as the current property. See the React docs for more details.

{
  current: ... // my ref content
}

Considering this, you should be able to sort this out by hand:

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>
  );
}

A simple way to go about this is documented below.

Note: the ref attribute on elements takes a function and this function is later called with the element or node when available.

function App() {
  const myRef = useRef(null);

  return (
    <div ref={myRef}>
    </div>
  );
}

Hence, myRef above is a function with definition

function(element){
 // something done here
}

So a simple solution is like below

function App() {
  const myRef = useRef(null);
  const anotherRef = useRef(null);

  return (
    <div ref={(el)=> {myRef(el); anotherRef(el);}}>
    </div>
  );
}

ref={((el: HTMLDivElement) => setNodeRef(el)) && ref} this still doesnt work for me. It produces no js error but my dnd-kit th element stops being droppable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM