question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Discussion: atomFamily better alternative

See original GitHub issue

I’ve tried to use atomFamily or implement my own alternative. But looks like I had no succeess, so I decided to discuss my vision and ideas.

atomFamily drawback

As I understand atomFamily was copied from RecoilJS. While at first glance it might look good, trying to implement this pattern in real life fails shortly. That’s the problems I found.

Can’t fetch or load data to atomFamily

Most often in real life before starting managing atoms we need to fetch data from somewhere - from local database or server. We don’t want to do multiple requests for each atom from atomFamily. While our strategy is to do the least requests returning most data, these requests will be highly specialized.

For example I have sqlite tags table

id label iconName iconColor isSelected
e8a63d19-ae64-44df-b3a8-0adbf7df1155 Family users rgba(227, 95, 166, 1) 1
7d3bfd19-3c88-4d12-8665-ddd405af5aee Health heartbeat rgba(242, 108, 108, 1) 0
6f07bc4e-79b1-44d2-b65e-460422ba137a Home home rgba(89, 212, 220, 1) 0
18efd821-9088-48a1-9bf7-2db589e69621 Shopping shopping-basket rgba(114, 180, 31, 1) 0
eb6a269b-66c7-4a6e-a588-ebff855800d1 Friends user-friends rgba(236, 122, 86, 1) 0
8d9d7cd1-12a9-4d60-90be-7c028bbcfc18 Grooming cut rgba(217, 110, 117, 1) 0

and I want to make one request to load data

const tagRepository = getTagRepository();
return tagRepository.find()

atomFamily do not allow to do that

atomFamily requires separate atom to manage ids

atomFamily requires to manage separate atom with list of ids. But most entities from server or local database already have id as part of its data.

  • additional request to load ids is required
  • separate atom with ids requires additonal coordination which complicates code
@Entity({ name: 'tags' })
export class Tag {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column('text')
  label!: string;
  ...
}

atomFamily doesn’t give performance advantage

If we add new todo to todoList https://github.com/jacques-blom/recoil-todo-list/blob/ccbec84f3a438b8707f235263bf079fab4bbd987/src/components/Input.tsx#L31

    const insertTask = useRecoilCallback(({set}) => {
        return (label: string) => {
            const newTaskId = tasks.length
            set(tasksState, [...tasks, newTaskId])
            set(taskState(newTaskId), {
                label: label,
                complete: false,
            })
        }
    })

this updates tasksState atom with ids.

export const tasksState = atom<number[]>({
    key: 'tasks',
    default: [],
})

const tasks = useRecoilValue(tasksState)

    return (
        <div>
            {tasks.map((id) => (
                <Task id={id} key={id} />
            ))}
        </div>
    )

so all <Task /> components will be rerendered again (but reconcilation - real DOM update - should happen only for updated task). I think there is no difference then just updating one big atom with list of todos.

The only advantage for atomFamily is when we update one atom - that should lead to updating only one component. But atomFamily doesn’t solve insert / delete use-cases.

Also, if we have example with filtered todo-list

const filteredTasksAtom = atom(
  get => {
    const allTasks = get(allTasksAtom)
    return allTasks.filter(<some condition>)
  }
)

this is more like a toy example. We might not have all tasks in memory. In real code we will have to load filtered tasks from server / database using query.

const filteredTasksAtom = atom(
  get => {
    return fetch('/tasks?isCompleted=0&isTracked=1')
  }
)

How to coordinate allTasksAtom and filteredTasksAtom because they might overlap? Since fetch('/tasks?isCompleted=0&isTracked=1') might return updated data we want to update existing atoms with this updated information from request, add new atoms and delete old ones. So we want to sync them.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
likerncommented, Dec 1, 2020

@dai-shi I’ve got some experience and it looks like it’s working. But I’m short on time. As soon as I will have more time I’ll fill in more information. Close for now.

1reaction
likerncommented, Nov 15, 2020

@likern I think we need your input.

I’ve switched to Recoil for my application. It has exactly the same requirements - filtered todo list.

I’m still investigating. But looks like I solved all problems (with hacks) and soon will share experience.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Need help on Recoil implementation : r/reactjs - Reddit
On my Atoms file I have: //Atoms.ts export const CustomAtomFamily = atomFamily< string | null, number >({ key: "CustomAtomFamily", default: null ...
Read more >
Jotai vs. Recoil: What are the differences? - LogRocket Blog
Jotai and Recoil both have their benefits. This article compares the state management libraries to help you decide what's best for you.
Read more >
Recoil to Jotai (with Typescript) - DEV Community ‍ ‍
Our consulting team has enjoyed using several excellent react libraries such as react-spring, react-t... Tagged with recoil, jotai, ...
Read more >
Recoil Patterns: Hierarchic & Separation | Weknow.Network
This article will discuss practical patterns in Recoil. It's an advance topic that goes beyond Recoil basics, so we won't spend time ...
Read more >
React JS & Recoil set/get on select/selectFamily for specific ...
There are some bugs in your code: no const , braces in atom call and no get inside the set . You also...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found