Recoil: Should the RecoilRoot and unique atom/selector keys be necessary?

Created on 12 Jul 2020  Â·  2Comments  Â·  Source: facebookexperimental/Recoil

I am concerned with how this scenario would be appropriately handled when relying on the context API to deliver the atom's state, as opposed to encapsulating the state in the atom itself:

// node_modules/my-lib
export function MyLibraryComponent({ children }) {
  return (
    <RecoilRoot>
      <StatefulHeader />
      {children}
      <StatefulFooter />
    </RecoilRoot>
  );
}
import { MyLibraryComponent } from 'my-lib';

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

When my StateFulChild uses useRecoilState to access an atom in App's RecoilRoot, it will instead be pulling from MyLibraryComponent's RecoilRoot. Debugging this sounds like a nightmare.

If the state were encapsulated in the atom itself, there would be no need for the RecoilRoot at all, and potential conflicts like this would never exist.

I'm not convinced the use of the context API (as mandatory, or as it is implemented today) is the correct choice. I'd love to either be convinced otherwise, or to know that it's not too late to change it while this product is still experimental.

Most helpful comment

Agreed. I'd like to add that I don't feel like it's an anti-pattern for component libraries to use Recoil. It's easy enough to say "They shouldn't have done that," but I think it makes sense for component libraries to use shared state. In some way, it should be supported.

<RecoilRoot> // ⬅ RecoilRoot A
  <MyStatefulApp> // ⬅ uses RecoilRoot A
    <ThirdPartyTable> // ⬅ RecoilRoot B
      <ThirdPartyRow> // ⬅ uses RecoilRoot B
        <ThirdPartyCell> // ⬅ uses RecoilRoot B
          <MyStatefulData /> // ⬅ wants to use RecoilRoot A

All 2 comments

The question of what happens if a third-party library HOC contains a RecoilRoot definitely spooks me.

Agreed. I'd like to add that I don't feel like it's an anti-pattern for component libraries to use Recoil. It's easy enough to say "They shouldn't have done that," but I think it makes sense for component libraries to use shared state. In some way, it should be supported.

<RecoilRoot> // ⬅ RecoilRoot A
  <MyStatefulApp> // ⬅ uses RecoilRoot A
    <ThirdPartyTable> // ⬅ RecoilRoot B
      <ThirdPartyRow> // ⬅ uses RecoilRoot B
        <ThirdPartyCell> // ⬅ uses RecoilRoot B
          <MyStatefulData /> // ⬅ wants to use RecoilRoot A
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ymolists picture ymolists  Â·  3Comments

robsoncezario picture robsoncezario  Â·  3Comments

yuantongkang picture yuantongkang  Â·  3Comments

pesterhazy picture pesterhazy  Â·  4Comments

eLeontev picture eLeontev  Â·  3Comments