Tao Chen
Tao Chen

Reputation: 285

recoil cannot handle the error of async selector

Recoil allows user to throw error in the async selector, please see its document to know more.

Both "<ErrorBoundary/>" and "useRecoilValueLoadable()" can be used to process errors of aysnc selector, but both of them can not work normally when I test them.

Here is my code by using "useRecoilValueLoadable()"

import {RecoilRoot, selector, useRecoilValueLoadable} from 'recoil';

const asyncError = selector({
  key: 'asyncError',
  get: async() => { throw new Error("Test Error"); }
});

function Test() {
  const loadable = useRecoilValueLoadable(asyncError);
  return (
    <h1>
      { loadable?.state === 'hasError' ? "Has error" : "No error" }
    </h1>
  );
}

function App() {
  return (
    <RecoilRoot>
      <Test/>
    </RecoilRoot>
  );
}

export default App;

But, the final result is

enter image description here.

I tried to use <ErrorBoundary/> and got the same unexpected result too! The version of recoil is "0.2.0".

Hi guys, how to resolve this problem? Thanks.

Upvotes: 2

Views: 2745

Answers (1)

Johannes Klau&#223;
Johannes Klau&#223;

Reputation: 11020

There is no built in ErrorBoundary component in React. You have to provide one yourself or use a library, for example react-error-boundary.

Then you also have to use React.Suspense just like the documentation you referred to states.

export default function App() {
  return (
    <RecoilRoot>
      <ErrorBoundary FallbackComponent={Fallback}>
        <React.Suspense fallback={<div>loading...</div>}>
          <Test />
        </React.Suspense>
      </ErrorBoundary>
    </RecoilRoot>
  );
}

Also your selector is not async. The error will throw immediately.

Check out this sandbox for a working example. To learn more about the function of the ErrorBoundary component you should read the official react docs.

Upvotes: 2

Related Questions