Understanding atomFamily and selectorFamily in Recoil

Aditya PradhanAditya Pradhan
2 min read

What is atomFamily?

For example, there is a dashboard supports multiple users, and each user has unique settings (theme, font size, notifications). You need to store and manage settings dynamically for each user without creating multiple individual atoms. How will you do it? Of course you can make separate atoms for each user but if there are thousands of users?

Here, atomFamily is used.

atomFamily allows us to create an atom dynamically based on a unique key instead of defining multiple atoms manually.

import { atomFamily } from 'recoil';

interface userPreferencesStateInterface {
    theme: string,
    fontSize: number
}

const userPreferencesState = atomFamily<userPreferencesStateInterface>({
  key: 'userPreferencesState',
  default: { theme: 'light', fontSize: 24 },
});

Now, different components can retrieve a unique instance of userPreferencesState using a user ID:

import { useRecoilState } from 'recoil';

const UserSettings = ({ userId }: { userId: string }) => {
  //Dynamic atoms with respect to userId
  const [preferences, setPreferences] = useRecoilState(userPreferencesState(userId));

  return (
    <div>
      <p>Theme: {preferences.theme}</p>
      <p>Font Size: {preferences.fontSize}</p>
      <button onClick={() => setPreferences((prev) => ({ ...prev, theme: 'dark' }))}>
        Switch to Dark Mode
      </button>
    </div>
  );
};

What is selectorFamily?

selectorFamily works similarly to atomFamily, but instead of storing state, it allows the creation of dynamic derived state. This means we can compute values based on parameters.

When to Use selectorFamily

  • When you need to compute derived state dynamically based on input parameters.

  • When filtering, transforming, or aggregating data dynamically.

  •     import { selectorFamily } from 'recoil';
    
        const userFullNameSelector = selectorFamily<string, string>({
          key: 'userFullNameSelector',
            //get method to fetch Value
          get: (userId) => ({ get }) => {
            const user = get(userPreferencesState(userId));
            return `User ID: ${userId} - Theme: ${user.theme}`;
          },
        });
    

    Now, we can use this selector to get computed state dynamically:

  •     import { useRecoilValue } from 'recoil';
    
        const UserProfile = ({ userId }: { userId: string }) => {
          const userFullName = useRecoilValue(userFullNameSelector(userId));
    
          return <p>{userFullName}</p>;
        };
    

Key Differences Between atomFamily and selectorFamily

FeatureatomFamilyselectorFamily
Stores state
Computes derived state
Used for dynamic instances
Can havve default values
Modifies Stored State
Dependent on other atoms/selectors

Conclusion

atomFamily and selectorFamily are essential tools in Recoil for managing dynamic state efficiently. While atomFamily helps in handling multiple unique state instances, selectorFamily is perfect for deriving computed state dynamically without modifying the stored state. By leveraging these tools, you can build more scalable and performant React applications.

0
Subscribe to my newsletter

Read articles from Aditya Pradhan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Aditya Pradhan
Aditya Pradhan

Passionate and curious software developer with experience in building impactful web applications and solving complex problems. Skilled in React, Node.js, TypeScript, and database systems, with a focus on creating efficient and scalable solutions. Worked on dynamic projects, including developing dashboards, student portals, and API-driven platforms.. A continuous learner and enthusiastic collaborator, always open to exploring innovative ideas and opportunities. Let’s connect and create something meaningful! 🚀