# 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{:.keyword}`, `aria-describedby{:.keyword}`, etc.)
inside a prop getter key, which get merged. You can do the same
thing.

<Notice>
  The library is fully tree-shakeable, so we can add new hooks
  for specific commonly requested features. If you have ideas for
  new hooks or functionality, don't hesitate to open a new issue
  or discussion on the [GitHub
  repo](https://github.com/floating-ui/floating-ui)!
</Notice>

```ts
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:

```js
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:

```js
const {context} = useFloating();

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