React child component can't get the atom value in Recoil

React child component can't get the atom value in Recoil
Page content

I’ve been using Recoil, a state management library for React, for a while now, so I’ll write some tips.

Environment

  • react 16.14.x
  • recoil 0.1.2

Cannot get atom value from child component in Recoil

While implementing a medium-sized application using Recoil, I encountered an issue where I could not get the value of atom from certain child component. Of course, I called <RecoilRoot> close to the top level components of the application such as App.tsx.

Use RecoilBridge for implementations that break the React Context

If there is a component in the Render Tree that does not pass the context state, it is necessary to bridge the context state before and after the corresponding component. For example, in the API of the <Canvas> tag in react-three-fiber, you need to bridge the context.

As a way to bridge, Recoil provides useRecoilBridgeAcrossReactRoots_UNSTABLE API. However, since the name is given as UNSTABLE, you should judge by yourself when to use it.

In the following sample code, the value of atom of Recoil can be used in components after <SomeChildComponent>.

 1const SomeComponent: React.FC = () => {
 2
 3  const RecoilBridge = useRecoilBridgeAcrossReactRoots_UNSTABLE();
 4
 5  return (
 6    <Canvas
 7      camera={{ fov: 50, aspect: 4.0 / 3.0, near: 0.4, far: 1.0 }}
 8    >
 9      <RecoilBridge>
10        <SomeChildComponent />
11      </RecoilBridge>
12    </Canvas>
13  )
14}

The approach to state management itself is different, but if you use a React Context that you defined yourself with React.createContext, you usually need to bridge it as follows. You can see that RecoilBridge is simple to look at as well.

 1const SomeComponent: React.FC = () => {
 2
 3  return (
 4    <SomeContext.Consumer>
 5      {(value) => (
 6        <Canvas
 7          camera={{ fov: 50, aspect: 4.0 / 3.0, near: 0.4, far: 1.0 }}
 8        >
 9          <SomeContext.Provider value={value}>
10            <SomeChildComponent />
11          </SomeContext.Provider>
12        </Canvas>
13      )}
14    </SomeContext.Consumer>
15  )
16}

Conclusion

  • If a child component cannot refer to an atom in an application using Recoil, there may be a component that has not passed the context state.
  • Can be referenced by using useRecoilBridgeAcrossReactRoots_UNSTABLE.
  • Note that the API is UNSTABLE.