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.
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
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.