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.

Make value of atomFamily an object, but pass in serializable key as param

See original GitHub issue

I’m doing something like this:

export const userListState = selector({
  key: 'userStateList',
  get: async () => {
    const resp = await fetch('/api/users')
    const users = await resp.json()

    users.forEach((user) => userState(user)

    return users.map(({ key }) => key))
  },
})

export const userState = atomFamily({
  key: 'userState',
  default: user => user
})

Ideally, within my app, I’d like to iterate through userListState, and and map an array of <User userKey={key} /> components

const User = ({ userKey }) => {
  const user = useRecoilValue(userState(userKey))
  ...
}

But given the way I instantiate each userState atom, I can’t pass the key in, I need to pass the entire object. So in a perfect world, the API for the default function would look like this:

const userState = atomFamily({
  'userState',
  default: (key, user) => user
})

I can get deeper into the need for this design, with each user having its own atom, as opposed to an atom consisting of a single array containing all users, but hopefully it’s not needed right now.

Does the API support something like this, or is there some kind of pattern I can apply? Loving recoil, but I’m hitting a wall with this!!

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
Shmewcommented, Jun 16, 2020

I’m not a JS developer, but something like:

export const userListState = selector({
    key: 'userStateList',
    get: async () => {
        const resp = await fetch('/api/users')
        const users = await resp.json()

        const userEntries = users.map((user, i) => [i, user])
        return new Map(userEntries);
    },
})

export const getUserListState = selectorFamily({
    key: 'getUserListState',

    get: id => ({ get }) => {
        return get(userListState).get(id)
    }
})

export const userState = atomFamily({
  key: 'userState',
  default: id => getUserListState(id)
})
1reaction
Shmewcommented, Jun 16, 2020

Correct, the “key” for userInfoState is the UserInfo that is returned by the query.

One potential problem with this is it can cause a memory leak if the atoms are persisted until #56 lands, or if your query is a selectorFamily (and called frequently) rather than a selector.

I should also mention that once #314 lands doing this kind of thing will be much less complex, as you can simply create an atom that has that selector as the default value and wrap it with a selectorFamily and modify it as you wish.

Read more comments on GitHub >

github_iconTop Results From Across the Web

atomFamily(options) - Recoil
Therefore, parameters are compared using value-equality and must be serializable. To be serializable it must be either: A primitive value; An array, object,...
Read more >
Dynamic atom keys in Recoil - reactjs - Stack Overflow
When you call atomFamily it will return a function which provides the RecoilState atom based on the parameters you pass in. The atomFamily...
Read more >
atomFamily() - Recoil 中文文档
But, Recoil provides this pattern for you with the atomFamily utility. ... atom with a unique key based on serialization of the parameter...
Read more >
How to pass class object as parameter - CodeProject
PRODUCTLIST[0] before you do the above assignment? Because that's all you're doing - assigning a new value to the first element in the...
Read more >
Persistent Recoil Storage - Alex Anderson
If you're sharing state between browsers and computers, you can use an API call to send it to a server database, serialize it...
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