Skip to content
This repository has been archived by the owner on Jan 1, 2025. It is now read-only.

Question: Fetch atoms/selectors via "key"? #181

Closed
soluml opened this issue May 27, 2020 · 8 comments
Closed

Question: Fetch atoms/selectors via "key"? #181

soluml opened this issue May 27, 2020 · 8 comments
Labels
question Further information is requested

Comments

@soluml
Copy link

soluml commented May 27, 2020

According to the docs, each atom/selector need to be given a unique key. Is it possible/planned to get an atom/selector by this key? If not, is there a way the library could generate a unique key without forcing the user to provide it?

// ...somewhere in the app...
const tempFahrenheit = atom({
  key: 'tempFahrenheit',
  default: 32,
});
//

const [tempF, setTempF] = useRecoilState('tempFahrenheit');

Just trying to get a better understanding of the library. Thanks :)

@soluml soluml changed the title Fetch atoms/selectors via "key"? [question] Fetch atoms/selectors via "key"? May 27, 2020
@soluml soluml changed the title [question] Fetch atoms/selectors via "key"? Fetch atoms/selectors via "key"? May 27, 2020
@soluml soluml changed the title Fetch atoms/selectors via "key"? Question: Fetch atoms/selectors via "key"? May 27, 2020
@itsMapleLeaf
Copy link

itsMapleLeaf commented May 27, 2020

If my understanding of the issue is right, this is something you can do with atomFactory (when it's released on npm, still waiting on #105)

const tempAtom = atomFactory({
  key: 'temp',
  default: () => 32,
})

function Component() {
  const [tempKey, setTempKey] = useState('tempFahrenheit')
  const temp = useRecoilValue(tempAtom(tempKey))
  // ...
}

I've been using a memoize function in the meantime, as mentioned in the library talk

@soluml
Copy link
Author

soluml commented May 27, 2020

@kingdaro - Not sure it's exactly the same thing. I may not have been clear enough. Let me try to expound. Essentially, my primary question is: Why do atom's and selector's have keys that are specified by the developer?

From that, two additional thoughts/questions emerged as alluded to in my original post:

  1. Is there a way to reference an atom/selector by the key alone? Most code examples either have the atom/selector in the same file or they import the atom/selector from a different file. Since the keys must be unique in the project, why can't I just provide the serialized key as the first argument to useRecoilState as I do in my original code example?

^ My hope here is to either get a better understanding of why the key is necessary or to see if this is a planned feature in a future release. Or maybe this already works? Like I said, just trying to better understand the library 👍

  1. If there are no plans to add the functionality above, why do I, the developer, need to provide a unique key at all? Can't the library figure out how to uniquely identify these things internally? Currently, the key doesn't seem to have any relevance to the developer other than the developer needs to ensure that the key is unique which feels like an unnecessary hassle. I'm sure there's a reason, I just wasn't sure why and thought I'd ask!

@acutmore
Copy link

Hi @soluml ,

There is some information about the use of keys in #32

The main thing keys are used for is persistence
#32 (comment)

But, keys are intended to be used in a few use-cases where a persistent value is needed. For example, they are used to persist atom state in some way such as the URL, a backing store DB, etc. Another example is exposing the atom or selector in developer tools for debugging. (This hasn't been published yet)
#32 (comment)

@soluml
Copy link
Author

soluml commented May 27, 2020

@acutmore - Thanks for your reply! #32 helps a lot in clarifying things as to why we have keys. Have there been any discussions on making the key optional? As in, have the library generate the string when a unique key is not provided? I guess I personally see myself running into key conflicts (with a team of developers on large projects) more so than needing to persist the unique key of an atom.

And also, just to reiterate my first question above. Since we have unique keys, are there any plans to reference atoms/selectors by those keys like in the example above?

@drarmstr
Copy link
Contributor

We've discussed this internally. There were some proposals to add Recoil "zones/contexts", which would help solve the key namespace concern and help with composability. Though, this isn't the highest priority at the moment. In the meantime, we use conventions for namespacing keys, e.g. 'Module/Key'.

No current plans to allow non-opaque strings as atom/selector handles in the API. Generally we want to enforce that you're actually working with the same shared atom/selector, provide protection from string typos, etc. It has worked pretty well to export shared atoms/selectors from shared modules that can be imported from the components or selectors that need them.

@drarmstr drarmstr added the question Further information is requested label May 27, 2020
@Shmew
Copy link

Shmew commented May 28, 2020

I'm not sure if it's considered a "best practice", but when implementing bind and map, I just took the key of the passed in value then appended /map (or /bind) + a hash of the function. Seems to work well so far, made composing/creating pipelines really nice.

@alexturpin alexturpin mentioned this issue May 29, 2020
@ShanonJackson
Copy link

Don't like fetch by key because could lead to weird behaviour where the atom itself isn't included in the bundle because no-one imports it because it's just being referenced by key name.

@sundayhd
Copy link

Yes you can. just warp it with object with key property and the atom key.

for example:

export const customersAtom = atom({
    key: 'customersAtom',
    dangerouslyAllowMutability: true,
    default: [1, 2, 3],
})

const someFunc = useRecoilCallback(({snapshot}) => async () => {
    const content = await snapshot.getPromise({"key": "customersAtom"});
    console.log(content); // should print [1, 2, 3]
}, [])

The atom itself can be on other file, you dont need to import it, just pass the atom key as a string and it should work (at least for now... 😁).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

7 participants