-
Notifications
You must be signed in to change notification settings - Fork 670
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: Why can't we support createAsyncSelector
?
#691
Comments
That's actually the problem. A selector is, by definition, 100% synchronous and pure (same as a reducer, actually). It gets called synchronously, is expected to return a value immediately, and that value is based solely on the arguments that were passed in (typically the Redux store You can write other async function that are similar (in that they take the state as an argument), but they would no longer be selectors. Where and how would you expect to use one of these "async selectors"? |
Appreciate very quick response 🙏 We use https://jsonata.org. It's very simple query language that "unfortunately" works async (in a future version). Here is a simplified example: const asyncSelector = createAsyncSelector(
(state) => state.a,
(state) => state.b,
async (a, b) => {
const context = { a, b }
return await jsonataEvaluator("a+b", context)
} Then in React world I would do this: function PrintAsyncSelector() {
const result = useSelector(asyncSelector)
return <p>{result}</p>
}
function Component() {
return (
<Suspense>
<PrintAsyncSelector />
</Suspense>
)
} The Another use case would be in "side effects". If you want to get current and derivated data from the store in callback executed on click. function Button() {
const onSubmit = async () => {
const result = await asyncSelector(store.getState())
await doRestCallWithCurrentValue(result)
}
return <Button onClick={onSubmit}>Submit</Button>
} I know I could do the Hope it makes sense. |
Yeah, unfortunately that won't work with Redux. What are you actually trying to retrieve with JSONata? is it actual data in the Redux store state? |
Yes, it is data in the Redux store. It is very complex network of I guess I could do something like this: function useHook() {
const [result, setResult] = useState()
const context = useSelector(collectDataFromRedux)
useEffect(() => {
setResult(await jsonataEvaluator("a+b", context))
}, [context])
return result
} But that complicates the code and it feels like unnecessary work-around of React's Suspense. |
you could try using the suspense util library for it? |
Part of the issue is it seems like the entire |
Sorry, maybe it is just a lack of knowledge about all these libraries. But if I am not wrong there is no problem of making We use The problem is the connection between React and Redux, where I put together this code sandbox that might better illustrate what I mean - https://codesandbox.io/p/sandbox/use-external-storage-forked-yflsy3 Please let me know if I am missing something |
IMO async selectors are the missing key for Redux state management when it comes comparisons of atom-based state libraries. They'd would be a huge upgrade, even if implemented somewhat separately, given the reasons @markerikson mentions here |
@kyranjamie : can you give an example of what a notional "async selector" API would look like, how it would be used, and thoughts on it would work? |
Say I'm working on an app that has to perform expensive cryptographic operations on an underlying key in a Redux store. Assume a library exposes some logic to derive child key information via an async method. const rootKey = createSelector(state => state.key);
const childKey = createAsyncSelector(rootKey, async key => await deriveChildKey(key));
function LayoutComponent () {
const childKey = useAsyncSelector(childKey); // suspends or has default value of `undefined`
return <KeyView childKey={key} />;
} This is super easy in a library like Jotai. I've actually refactored an app to Redux from Jotai and the lack of an API like this is the biggest pain point. |
That is effectively the RTK Query |
Hey folks! 👋 First of all, great work on this library! 👏
I have a question. I'd like to understand where the problem lies. I know that
reselect
doesn't support async selectors, and if we need to fetch data, we should use a thunk or another approach. That's fine and it works. But what if we need to use, let's say, a 3rd party library inside of a selector that computes something, but does that only in an async way?For example, something like this:
Also, if I want to use this as the input of another async selector:
I would just like to understand why this is considered an antipattern. Why can't we support this? This is not a case of fetching data; it's deriving data from the Redux store asynchronously.
The text was updated successfully, but these errors were encountered: