Skip to content

定制钩子

¥Custom Hooks

你可以构建自己的自定义 Hook 来执行库当前未导出的独特逻辑。

¥You can build your own custom Hook to perform unique logic that is not currently exported by the library.

库导出的 Hook 本质上只是在 prop getter 键内返回 HTML props(onClickaria-describedby 等),然后进行合并。你也可以做同样的事情。

¥The Hooks exported by the library essentially just return HTML props (onClick, aria-describedby, etc.) inside a prop getter key, which get merged. You can do the same thing.

const useCustomLogic = (
  context: FloatingContext,
): ElementProps => {
  const referenceProps = useMemo(
    () => ({
      // React.HTMLProps
      onClick: () => console.log('clicked'),
    }),
    [],
  );
  const floatingProps = useMemo(
    () => ({
      // React.HTMLProps
    }),
    [],
  );
  const itemProps = useMemo(
    () => ({
      // React.HTMLProps
    }),
    [],
  );
 
  // All 3 of these properties are optional.
  return useMemo(
    () => ({
      reference: referenceProps,
      floating: floatingProps,
      item: itemProps,
    }),
    [referenceProps, floatingProps, itemProps],
  );
};

Hook 之间的通信

¥Communicating between Hooks

交互 Hook 是解耦的,因此将共享上下文对象作为第一个参数传递是它们相互通信的方式。

¥Interaction Hooks are decoupled, so passing the shared context object as a first argument is how they communicate with each other.

它附加了一个事件触发器:

¥It has an event emitter attached:

const {context} = useFloating();
 
useEffect(() => {
  const handleEvent = () => {};
  context.events.on('name', handleEvent);
  return () => {
    context.events.off('name', handleEvent);
  };
}, [context.events]);
 
return (
  <div
    onClick={() => {
      context.events.emit('name', {foo: 'bar'});
    }}
  />
);

还有一个可变引用来传递 Hook 周围的状态变量:

¥And also a mutable ref to pass state variables around Hooks:

const {context} = useFloating();
 
useEffect(() => {
  context.dataRef.current.foo = 'bar';
}, [context]);