When building complex React applications, we often deal with multiple instances of similar pieces of state. Managing each one separately with individual atoms can quickly become messy and repetitive. Recoil provides a powerful utility called atomFamily to solve this problem.
In this article, we’ll break down what atomFamily is, why it’s useful, and how it works in the context of a Todo app.
What is atomFamily?
atomFamily is a factory function that allows us to create parameterized atoms.
- Instead of writing separate atoms for each todo, we can create one family of atoms.
- Each atom inside the family is uniquely identified by its parameter (like an
id). - This makes managing dynamic state instances (e.g., multiple todos, users, or chat rooms) simple and scalable.
Example Code Walkthrough
Let’s break down your provided example.
1. Defining the Atom Family
import { atomFamily } from "recoil";
import { TODOS } from "./todos";
export const todosAtomFamily = atomFamily({
key: "todosAtomFamily",
default: (id) => {
return TODOS.find((todo) => todo.id == id);
},
});
-
atomFamilycreates a group of atoms for todos. - Each atom is accessed using
todosAtomFamily(id). - The
defaultvalue depends on the givenid, pulling data from the staticTODOSarray.
This way, each id corresponds to a unique atom.
2. Using Atoms in Components
function Todo({ id }) {
const todo = useRecoilValue(todosAtomFamily(id));
return (
<>
{todo.title}
{todo.description}
<br />
</>
);
}
-
useRecoilValue(todosAtomFamily(id))retrieves the specific todo state. - Each
Todocomponent renders the title and description for its assignedid.
3. Updating State
function UpdatedTodo() {
const updateTodo = useSetRecoilState(todosAtomFamily(2));
useEffect(() => {
setTimeout(() => {
updateTodo({
id: "2",
title: "I can change anything",
description: "I am safal",
});
}, 2000);
}, []);
return <div>Hello</div>;
}
-
useSetRecoilState(todosAtomFamily(2))gives us a setter for the todo withid = 2. - After 2 seconds, the todo is updated with a new title and description.
- Because all components using
todosAtomFamily(2)share the same state, they re-render automatically with updated values.
4. Main Application
function App() {
return (
<RecoilRoot>
<Todo id={1} />
<Todo id={2} />
<Todo id={2} />
<Todo id={2} />
<Todo id={2} />
<Todo id={2} />
<UpdatedTodo />
</RecoilRoot>
);
}
- Multiple
<Todo id={2} />components all subscribe to the same state (todosAtomFamily(2)). - When
UpdatedTodomodifies that state, all instances ofid=2automatically update.
Key Benefits of Using atomFamily
✅ Avoids repetition – no need to manually define separate atoms for each todo.
✅ Dynamic state – you can create atoms on-the-fly using parameters (like id).
✅ Shared updates – if multiple components reference the same atom, updating it in one place updates all.
✅ Scalable – great for managing lists, collections, or items fetched from APIs.
When to Use atomFamily?
- Managing state for items with unique identifiers (todos, users, products, etc.).
- Creating multiple instances of the same kind of state dynamically.
- Sharing state across different components that depend on the same key.
Final Thoughts
Recoil’s atomFamily is one of the most powerful features when working with lists of dynamic data. In this todo example, you’ve seen how easy it becomes to create, read, and update multiple todo items without duplicating state logic.
If your app needs per-item state management, atomFamily should be your go-to tool.
Top comments (0)