Zum Inhalt springen

Understanding atomFamily in Recoil with a Todo Example

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);
  },
});
  • atomFamily creates a group of atoms for todos.
  • Each atom is accessed using todosAtomFamily(id).
  • The default value depends on the given id, pulling data from the static TODOS array.

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 Todo component renders the title and description for its assigned id.

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 with id = 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 UpdatedTodo modifies that state, all instances of id=2 automatically 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.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert