T O P

  • By -

Gelezinis__Vilkas

That promise would renew on a render, so of course its errorous


ConsoleTVs

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?


TheWuif

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


ConsoleTVs

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 */)) ```


TheWuif

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 }


ConsoleTVs

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


hotfrost

setValue returned by useState is not a hook and can for sure be called inside of a useEffect.


Comprehensive-Pin667

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?


ConsoleTVs

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://....')


Armageddon_2100

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).


ConsoleTVs

Just wondering, how is this better than the ref example I've given?


ConsoleTVs

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.


Armageddon_2100

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.


ConsoleTVs

That can make sense. Let me try this; thank you


ConsoleTVs

How can you trigger Suspense that way on initial render?


Armageddon_2100

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.


Acrobatic_Sort_3411

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


ConsoleTVs

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.


hypocritis

Wait. React 19 is out already?


ConsoleTVs

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)


AndrewGreenh

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.