Skip to content

Custom Hooks

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

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

Communicating between Hooks

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

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

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