React
React Design Patterns: Instance Hook Pattern
Sep 15, 2024
12 min read

# React Design Patterns: Instance Hook Pattern
When building components, it's important to keep the logic clean and reusable. One handy way to do this is by using the Instance Hook Pattern. I first discovered this pattern in Ant Design's `Form.useForm` hook.
## A Custom Hook with Added Steps
The basic idea: generally it is advisable for a component to handle its own state and logic. But sometimes, we might want to control that state from the outside. This pattern allows for this flexibility.
The Instance Hook Pattern ties a component's state and behavior to a custom hook. You can think of it like a remote control for the component—it gives the user control over specific actions.
Let's see this pattern in action with a simple `Dialog` component:
```javascript
// SomePage.tsx
import Dialog from "../components/ui/Dialog";
const SomePage = () => {
const dialogInstance = Dialog.useDialog();
return (
<>
Dialog is {dialogInstance.isOpen ? "open" : "closed"}
>
);
};
```
## What sets this apart from a Custom Hook?
1. Co-located Logic: The hook and component live together
2. Controlled API: The hook returns a set of functions and state that the user can interact with
3. Unified State: The component uses the packet of state that the hook provides internally
4. Totally Optional: The component can manage its own state by default
## Composability: Why this pattern is awesome
The real power comes when you have multiple instances of a component:
```javascript
const SomePage = () => {
const dialog1 = Dialog.useDialog();
const dialog2 = Dialog.useDialog();
return (
<>
>
);
};
```
## Behind the Scenes
```javascript
// Dialog.tsx
import { useDialog } from "./use-dialog";
export type DialogInstance = {
open: () => void;
close: () => void;
toggle: () => void;
isOpen: boolean;
};
const Dialog = ({ dialog, children }) => {
return (
{children}
);
};
export default Object.assign(Dialog, { useDialog });
```
## Conclusion
The Instance Hook Pattern is a simple design pattern in React that allows you to create reusable components with controlled behavior. I like to think of it as a packet of state which can be passed around anywhere to control the component linked to it.