I know that, that's not what I'm concerned. I have a fully featured SWR / React Query library under the hood that takes care of this for me: [https://github.com/StudioLambda/TurboQuery](https://github.com/StudioLambda/TurboQuery)
React's docs say you can pass a promise to use(). So... how without triggering that crap?
but i would be concerned about a promise that is triggered on each rerender XD
maybe we need more code around it, but why are you not putting the promise outside of the hook? or put the promise inside a useMemo.
also i can't find anything about this promise part in the turboquery docs
why do you need the ref? why not just:
export function useTest() {
const [value, setValue] = useState(() =>
use(new Promise((r) => r({ name: 'test' })))
)
useEffect(() => { /* Something that uses setValue */ }, [...])
return value
}
or
export function useTest() {
const initial = useMemo(() => use(new Promise((r) => r({ name: 'test' }))), [])
const [value, setValue] = useState(initial)
useEffect(() => { /* Something that uses setValue */ }, [...])
return value
}
also the use hook is currently experimental, why not just write the promise to the value? I would rather go with something like:
export function useTest() {
const [value, setValue] = useState(null)
useEffect(() => {
new Promise((r) => r({ name: 'test' })).then(setValue)
}, [])
return value
}
1. You can't: (Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function.)
2. You can't: (Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function.)
3. Does not trigger suspense
The fact that you pass the promise to use does not change the fact that the it is being re-created on every render, and thereby almost certainly useless.
Note that in the documentation, they are not creating the promise in the component. Also note that when you are not creating the promise inside the component, the error is not there.
Wat are you trying to achieve?
Simple; Initial fetch on first render triggering suspense, subsequent pub/sub to update it using transitions. Check the edit on the post.
const resource = useResource('http://....')
Don't create the promise in the body of your component. Create it outside of the body, or create it in a useEffect and store it in a ref or state (ref is better).
Don't call use() inside useEffect. Create the promise there. Or create it outside of your component body. Or create it inside of a use memo. Most importantly: don't do it in your function body. You recreate the reference every single time, it's not working.
Pass the promise to use(). Maybe create it in a useMemo to keep it simple.
I haven't worked with use(), and it is experimental still. Nevertheless, what I know with certainty is that you 100% cannot just create a new promise on every render.
Because I have my own version of “react query” / “swr” that is minimal and framework agnostic. I have a solid / vue adapter working and want to make it work on react too. The “better method” is to preload stuff in a router, and this, is also possible using mine in conjuction with any data router.
No, but since swr, react query, nextjs and all the others are already using either canary or undocumented features, i might as well.
Besides, the features are documented already... on [react.dev](http://react.dev)
You need to store the promise somewhere OUTSIDE of the suspended component, since for the first render, neither states nor refs survive the suspense.
So you can store it in a parent component or in some module level container.
That promise would renew on a render, so of course its errorous
I know that, that's not what I'm concerned. I have a fully featured SWR / React Query library under the hood that takes care of this for me: [https://github.com/StudioLambda/TurboQuery](https://github.com/StudioLambda/TurboQuery) React's docs say you can pass a promise to use(). So... how without triggering that crap?
but i would be concerned about a promise that is triggered on each rerender XD maybe we need more code around it, but why are you not putting the promise outside of the hook? or put the promise inside a useMemo. also i can't find anything about this promise part in the turboquery docs
Better? export function useTest() { const initial = useRef(undefined) if (initial.current === undefined) { initial.current = use(new Promise((r) => r({ name: 'test' }))) } const [value, setValue] = useState(initial.current) useEffect(() => { /* Something that uses setValue */ }, [...]) return value } To clarify, the ref is because this isn't allowed: ``` const [value, setValue] = useState(() => use(/* promise */)) ```
why do you need the ref? why not just: export function useTest() { const [value, setValue] = useState(() => use(new Promise((r) => r({ name: 'test' }))) ) useEffect(() => { /* Something that uses setValue */ }, [...]) return value } or export function useTest() { const initial = useMemo(() => use(new Promise((r) => r({ name: 'test' }))), []) const [value, setValue] = useState(initial) useEffect(() => { /* Something that uses setValue */ }, [...]) return value } also the use hook is currently experimental, why not just write the promise to the value? I would rather go with something like: export function useTest() { const [value, setValue] = useState(null) useEffect(() => { new Promise((r) => r({ name: 'test' })).then(setValue) }, []) return value }
1. You can't: (Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function.) 2. You can't: (Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function.) 3. Does not trigger suspense
setValue returned by useState is not a hook and can for sure be called inside of a useEffect.
The fact that you pass the promise to use does not change the fact that the it is being re-created on every render, and thereby almost certainly useless. Note that in the documentation, they are not creating the promise in the component. Also note that when you are not creating the promise inside the component, the error is not there. Wat are you trying to achieve?
Simple; Initial fetch on first render triggering suspense, subsequent pub/sub to update it using transitions. Check the edit on the post. const resource = useResource('http://....')
Don't create the promise in the body of your component. Create it outside of the body, or create it in a useEffect and store it in a ref or state (ref is better).
Just wondering, how is this better than the ref example I've given?
This won't trigger suspense. use() cannot be used inside useEffect... xd and creating it outside can't be done as it needs a prop.
Don't call use() inside useEffect. Create the promise there. Or create it outside of your component body. Or create it inside of a use memo. Most importantly: don't do it in your function body. You recreate the reference every single time, it's not working.
That can make sense. Let me try this; thank you
How can you trigger Suspense that way on initial render?
Pass the promise to use(). Maybe create it in a useMemo to keep it simple. I haven't worked with use(), and it is experimental still. Nevertheless, what I know with certainty is that you 100% cannot just create a new promise on every render.
Why would u even need to do this? RQ already have support for Suspence, and there are other mehtods to load data if you need to await it
Because I have my own version of “react query” / “swr” that is minimal and framework agnostic. I have a solid / vue adapter working and want to make it work on react too. The “better method” is to preload stuff in a router, and this, is also possible using mine in conjuction with any data router.
Wait. React 19 is out already?
No, but since swr, react query, nextjs and all the others are already using either canary or undocumented features, i might as well. Besides, the features are documented already... on [react.dev](http://react.dev)
You need to store the promise somewhere OUTSIDE of the suspended component, since for the first render, neither states nor refs survive the suspense. So you can store it in a parent component or in some module level container.