Understanding atomFamily and selectorFamily in Recoil


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
Feature | atomFamily | selectorFamily |
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.
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! 🚀