When building applications with Recoil, you often need to manage state that looks similar but is distinguished by some dynamic parameter — for example, user profiles, messages, or notifications that are stored individually. Defining a separate atom for each case would be repetitive and inefficient. This is where AtomFamily comes into play.
What is AtomFamily?
-
atomFamily
is a factory for atoms. - Instead of creating multiple atoms manually, you can create a function that generates unique atoms based on a parameter.
- Each atom created by the family behaves like a normal atom but is identified by the parameter you pass in.
This makes it perfect for dynamic data structures where you don’t know beforehand how many atoms you’ll need.
Syntax
import { atomFamily } from "recoil";
const myAtomFamily = atomFamily({
key: "myAtomFamily",
default: (param) => {
return `Default value for ${param}`;
},
});
Here:
-
key
→ Unique string to identify the atom family. -
default
→ Can be a value or a function of the parameter.
Example: User Profiles with AtomFamily
Imagine you’re building an app where you need to manage the profile data of multiple users. Instead of writing separate atoms for each user, you can use an atomFamily
:
import { atomFamily, useRecoilState } from "recoil";
const userProfileAtom = atomFamily({
key: "userProfile",
default: (userId) => ({
id: userId,
name: "",
age: null,
}),
});
function UserProfile({ userId }) {
const [profile, setProfile] = useRecoilState(userProfileAtom(userId));
return (
<div>
<h2>User: {profile.id}</h2>
<input
type="text"
value={profile.name}
onChange={(e) =>
setProfile({ ...profile, name: e.target.value })
}
/>
</div>
);
}
👉 Each userId generates its own atom instance, isolated from others.
Benefits of AtomFamily
- Dynamic Atoms – Generate atoms on demand based on parameters.
- Less Boilerplate – Avoid writing repetitive atom definitions.
- Scoped State – Each atom is isolated to its parameter, preventing accidental data mixing.
- Scalable – Perfect for apps that deal with dynamic lists like todos, users, or chat messages.
Example: Notifications with AtomFamily
const notificationAtom = atomFamily({
key: "notificationAtom",
default: (id) => ({
id,
text: "",
read: false,
}),
});
// Usage in component
function Notification({ id }) {
const [notif, setNotif] = useRecoilState(notificationAtom(id));
return (
<div>
<p>{notif.text}</p>
<button onClick={() => setNotif({ ...notif, read: true })}>
Mark as Read
</button>
</div>
);
}
Each notification gets its own atom state, managed separately.
When to Use AtomFamily?
- You need per-item state (e.g., one state for each todo, user, or chat room).
- You don’t know the number of atoms in advance.
- You want a factory-like approach to state management.
✅ In short, AtomFamily helps you dynamically create atoms for scalable, flexible state management — without duplicating code for every case.
Top comments (0)