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.

[NextJS / SSR] Can't use useRecoilValue in async selectors (ReactDOM does not yet support Suspense)

See original GitHub issue

Hi!

Following #720 issue (that I’ve opened), I’m trying to use the hook useRecoildValue in my NextJS application with a given atom that uses an async selector to fetch the default data.

Here is a sample code:

import { atom, selector } from 'recoil'

import { PREFIX } from './constants'

import { KeyResultsHashmap } from 'components/KeyResult'
import { getFromAPI } from 'state/actions/api'

export const KEY = `${PREFIX}::ALL`

export const selectAllRemoteKeyResults = selector<KeyResultsHashmap>({
  key: `${KEY}::REMOTE`,
  get: async () => getFromAPI<KeyResultsHashmap>('/key-results', KEY),
})

export const allKeyResults = atom<KeyResultsHashmap>({
  key: KEY,
  default: selectAllRemoteKeyResults,
})

With that given atom/selector, I’m trying to do the following in my component:

import React, { ReactElement } from 'react'
import { useRecoilValue } from 'recoil'
import { allKeyResults as allKeyResultsAtom } from 'state/recoil/keyResults/all'

const TestComponent = (): ReactElement => {
  const allKeyResults = useRecoilValue(allKeyResultsAtom)

  console.log(allKeyResults)

  return(<div>Test</div>)
}

When I run my application, I got the following error in my terminal:

2020-11-07 01:34:07:94 - KEY_RESULTS::ALL ➤ [INFO]: Dispatching GET request to /api/key-results
Error: ReactDOMServer does not yet support Suspense.
    at ReactDOMServerRenderer.read (/home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/react-dom-virtual-7df3ed46ef/0/cache/react-dom-npm-17.0.1-588d0088ca-6a70028fbe.zip/node_modules/react-dom/cjs/react-dom-server.node.development.js:3704:25)
    at renderToString (/home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/react-dom-virtual-7df3ed46ef/0/cache/react-dom-npm-17.0.1-588d0088ca-6a70028fbe.zip/node_modules/react-dom/cjs/react-dom-server.node.development.js:4298:27)
    at renderPage (/home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/next-virtual-6f4174843d/0/cache/next-npm-10.0.0-82dc2f1372-c01b177cb2.zip/node_modules/next/next-server/server/render.tsx:900:18)
    at Object.ctx.renderPage (webpack-internal:///./src/pages/_document.tsx:103:26)
    at Function.getInitialProps (webpack-internal:///./.yarn/$$virtual/next-virtual-6f4174843d/0/cache/next-npm-10.0.0-82dc2f1372-c01b177cb2.zip/node_modules/next/dist/pages/_document.js:141:19)
    at Function.getInitialProps (webpack-internal:///./src/pages/_document.tsx:114:83)
    at loadGetInitialProps (/home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/next-virtual-6f4174843d/0/cache/next-npm-10.0.0-82dc2f1372-c01b177cb2.zip/node_modules/next/next-server/lib/utils.ts:335:27)
    at renderToHTML (/home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/next-virtual-6f4174843d/0/cache/next-npm-10.0.0-82dc2f1372-c01b177cb2.zip/node_modules/next/next-server/server/render.tsx:909:48)
    at /home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/next-virtual-6f4174843d/0/cache/next-npm-10.0.0-82dc2f1372-c01b177cb2.zip/node_modules/next/next-server/server/next-server.ts:1382:26
    at /home/odelucca/Code/odelucca/execution-mode@budproj/.yarn/$$virtual/next-virtual-6f4174843d/0/cache/next-npm-10.0.0-82dc2f1372-c01b177cb2.zip/node_modules/next/next-server/server/next-server.ts:1318:25

For those who are not familiar with NextJS, it is a server-side rendered component for React. So, I understood that it is trying to render my component in server side, but it is breaking since the server-side does not support Suspense.

After that, I moved to useRecoilLoadable and it works, but I want to use useRecoilValue instead, to handle fallbacks more easily (with Suspense) and use ErrorBoundries too.

Anyone can help me?

Issue Analytics

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

github_iconTop GitHub Comments

8reactions
hamidihekmatcommented, Nov 10, 2020

You can use useRecoilValueLoadable to only get the loadable value. And if you want to access the state of the atom you can use the ['hasValue, ‘hasError’, ‘loading’] then render the appropriate components

This example is taken straight from the docs…

  const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
  switch (userNameLoadable.state) {
    case 'hasValue':
      return <div>{userNameLoadable.contents}</div>;
    case 'loading':
      return <div>Loading...</div>;
    case 'hasError':
      throw userNameLoadable.contents;
  }
}
0reactions
FahadAminShovoncommented, Nov 16, 2022

You can use useRecoilValueLoadable to only get the loadable value. And if you want to access the state of the atom you can use the ['hasValue, ‘hasError’, ‘loading’] then render the appropriate components This example is taken straight from the docs…

  const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
  switch (userNameLoadable.state) {
    case 'hasValue':
      return <div>{userNameLoadable.contents}</div>;
    case 'loading':
      return <div>Loading...</div>;
    case 'hasError':
      throw userNameLoadable.contents;
  }
}

Has issues with TypeScript.

probably because you don’t have a default case

Read more comments on GitHub >

github_iconTop Results From Across the Web

NextJS - ReactDOMServer does not yet support Suspense
I'm currently trying to incorporate a loader component to a site built with NextJS. I would like to use ...
Read more >
Using NextJs with async Recoil selectors?
I tried using this starter https://github.com/vercel/next.js/tree/canary ... Note: Suspense does not support SSR yet - you will need to lazy ...
Read more >
"Next.js で React.Suspense 使うのどうやるんだろ? SSR だと ...
[NextJS / SSR] Can't use useRecoilValue in async selectors (ReactDOM does not yet support Suspense)... Hi! Following #720 issue (that I've ...
Read more >
useRecoilValueLoadable(state)
Unlike useRecoilValue() , this hook will not throw an Error or Promise when reading from an asynchronous selector (for the purpose of using...
Read more >
Next.js で React Suspense が使えない
Error: ReactDOMServer does not yet support Suspense. ... [NextJS / SSR] Can't use useRecoilValue in async selectors (ReactDOM does not yet ...
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