[React] Use Async Functions in a Recoil Selector

Instead of just returning a value from a recoil selector, you can return any promise, which means that you can do asynchronous functions in recoil selectors (this is a little like a redux thunk).

The huge bonus is that you don't have to do anything different when actually calling the selector - use can use useRecoilValue in the same way that you would from a normal selector.

The only thing you must do is somewhere in the component tree, wrap any component that uses an async selector with a <React.Suspense> tag with a fallback prop that will tell React what to display when the async selector isn't loaded yet.

 

 Component:
import React from "react";

import { useRecoilValue } from "recoil";

import { highScores } from "./selectors";

const HighScore = () => {
  const score = useRecoilValue(highScores);

  return <div>High Score: {score}</div>;
};

export default HighScore;

 

Selectors.js:

import { selector } from "recoil";

import { gameScore } from "./atoms";

const fetchHighScores = async () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(303);
    }, 1000);
  });
};

const highScores = selector({
  key: "highScores",
  get: async ({ get }) => {
    return await fetchHighScores();
  }
});

export { highScores };

 

Use:

import React from "react";
import "./styles.css";

import { RecoilRoot } from "recoil";
import HighScore from "./HighScore";

function App() {
  return (
    <RecoilRoot>
      <div className="App">
        <React.Suspense fallback={<div>Loading...</div>}>
          <HighScore />
        </React.Suspense>
      </div>
    </RecoilRoot>
  );
}

export default App;

 

posted @ 2020-06-17 20:12  Zhentiw  阅读(399)  评论(0编辑  收藏  举报