Skip to content

useInteractions

用于将交互事件处理程序合并或组合在一起、保留记忆的钩子。

¥A hook to merge or compose interaction event handlers together, preserving memoization.

import {useInteractions} from '@floating-ui/react';

useHover()useFocus() 这样的交互钩子有两件事:它们在自身内部创建独立工作的效果,并返回旨在传递给元素以添加其功能的事件处理程序。

¥Interaction Hooks like useHover() and useFocus() do two things: they create Effects inside themselves that work independently, and also return event handlers intended to be passed to the elements to add their functionality.

用法

¥Usage

useInteractions() 接受从交互 Hooks 返回的值的数组,将它们的事件处理程序合并到用于渲染的 prop getter 中:

¥useInteractions() accepts an array of the values returned from interaction Hooks, merging their event handlers into prop getters used for rendering:

import {
  useFloating,
  useHover,
  useFocus,
  useInteractions,
} from '@floating-ui/react';
 
function App() {
  const {context} = useFloating();
 
  const hover = useHover(context);
  const focus = useFocus(context);
 
  const {getReferenceProps, getFloatingProps} = useInteractions([
    hover,
    focus,
  ]);
}

外部引用

¥External reference

在你的组件 API 中,参考元素可能位于调用 useFloating() 的组件的外部(传递定位数据的位置)。在这样的树结构中,交互在高于它们的 “root” 组件中的参考元素和浮动元素之间共享 - 两者的共同祖级。

¥In your component API, the reference element may be external to the component that useFloating() is called in (where the positioning data is passed). In such a tree structure, the interactions are shared between the reference element and floating element in a “root” component higher than them — an ancestor common to both.

例如:

¥An example would be:

<TooltipRoot> {/* useInteractions() called in this component */}
  <TooltipTrigger />
  <TooltipPopup /> {/* useFloating() called in this component */}
</TooltipRoot>

要共享参考元素和浮动元素之间的交互,你可以使用 useFloatingRootContext() Hook:

¥To share the interactions between the reference and floating elements, you can use the useFloatingRootContext() Hook:

import {useFloatingRootContext} from '@floating-ui/react';

它返回一个被所有交互钩子接受的 context object,类似于 useFloating() 返回的 context object - 只是没有定位数据。

¥It returns a context object that is accepted by all interaction Hooks, similar to the one returned by useFloating() — only without the positioning data.

将打开状态和元素传递给 Hook:

¥Pass the open state and elements to the Hook:

function TooltipRoot() {
  const [isOpen, setIsOpen] = useState(false);
 
  const [anchor, setAnchor] = useState(null);
  const [tooltip, setTooltip] = useState(null);
 
  const context = useFloatingRootContext({
    open: isOpen,
    onOpenChange: setIsOpen,
    // Required: both elements must be passed externally.
    // Store them in state.
    elements: {
      reference: anchor,
      floating: tooltip,
    },
  });
 
  const click = useClick(context);
 
  const {getReferenceProps, getFloatingProps} = useInteractions([
    click,
  ]);
 
  return (
    <>
      <Anchor setAnchor={setAnchor} {...getReferenceProps()} />
      <Tooltip
        rootContext={context}
        setTooltip={setTooltip}
        {...getFloatingProps()}
      />;
    </>
  );
}

根上下文必须通过将它作为 rootContext 选项传递来提供给 useFloating()

¥The root context must be available to useFloating() by passing it as the rootContext option:

function Tooltip({rootContext, setTooltip, ...props}) {
  const {floatingStyles} = useFloating({
    rootContext,
  });
  return <div ref={setTooltip} {...props} />;
}

返回值

¥Return value

interface UseInteractionsReturn {
  getReferenceProps(
    userProps?: React.HTMLProps<Element>,
  ): Record<string, unknown>;
  getFloatingProps(
    userProps?: React.HTMLProps<HTMLElement>,
  ): Record<string, unknown>;
  getItemProps(
    userProps?: React.HTMLProps<HTMLElement>,
  ): Record<string, unknown>;
}

Hook 返回两个核心 prop getter,一个用于引用元素,一个用于浮动元素。这些 prop getter 应该分布到元素上:

¥The Hook returns two core prop getters, one for the reference element and one for the floating element. These prop getters should be spread onto the elements:

<>
  <div ref={refs.setReference} {...getReferenceProps()} />
  <div
    ref={refs.setFloating}
    style={floatingStyles}
    {...getFloatingProps()}
  />
</>

你传入的所有事件处理程序都应该通过 prop getter 完成,而不是元素本身:

¥All event handlers you pass in should be done so through the prop getter, not the element itself:

<div
  ref={refs.setReference}
  {...getReferenceProps({
    onClick: () => console.log('clicked'),
    onFocus: () => console.log('focused'),
  })}
/>

这是因为你的处理程序可能被覆盖或覆盖 Hooks 的处理程序之一。未来版本中还可能添加更多事件处理程序。

¥This is because your handler may be either overwritten or overwrite one of the Hooks’ handlers. More event handlers may also be added in future versions.

getItemProps

在处理浮动元素内的列表时,会为 item 元素返回第三个 prop getter,这并不是所有类型的浮动元素都需要的。有关列表框(例如选择框或组合框)或菜单角色的 prop getter 的更多信息,请参阅 useRole

¥A third prop getter is returned for item elements when dealing with a list inside the floating element, which is not required for all types of floating elements. See useRole for more information on this prop getter for listbox (e.g. select or combobox) or menu roles.

const {
  getReferenceProps, 
  getFloatingProps, 
  getItemProps
} = useInteractions([]);