Search code examples
javascriptreactjsrecoiljs

Creating simple slice of state with recoil


I have an api request and I like to store the response in Recoil atom.
I am trying to figure out what is the best way of doing so.
The thing is that my selector doesn't have dependency (atom) since my request has no parameters:

const connectionsQuery = selector({
  key: "Connections",
  get: async () => {
    const connections = await findConnections();
    return connections;
  },
});

When I execute the following, I get on informative error: error

This is how I used the selector:

function DashboardLayout() {
  const classes = useStyles();
  const [isMobileNavOpen, setMobileNavOpen] = useState(false);
  console.log(222);
  const connections = useRecoilValue(connectionsQuery);
  console.log(333);
  ...
  ...

'222' console logged but '333' was never logged.

What am I missing?


Solution

  • You have to wrap your component with Suspense. awaiting a selector means that the component depending on the value of that selector will suspend rendering until there is a value, because Recoil internally will throw a promise (which is the whole idea behind suspending in React).

    So to make it work wrap your DashboardLayout component with a Suspense component:

    <React.Suspense fallback={<div>loading...</div>}>
      <DashboardLayout/>
    </React.Suspense>
    

    This is also stated in the recoil docs. To learn more about concurrent mode and suspense, you should read the official react docs to understand the mechanics behind it.