Using recoil.js in react, in class component without using hooks

Viewed 6514

I am new to recoil, and I am using all class components. Here is my recoil state

export const tokenState = atom({
  key: "tokenState",
  default: "",
});

How to use recoil in class component and set the token? I have used RecoilRoot in app as

<RecoilRoot>
  <Header />
  <Main />
</RecoilRoot>

In login.js, I want to set the token in recoil, but login.js is a class component.

const res = await APIS.login(apiRoute,requestObject);

In res.data.token I am getting the jwt token.

Thank you in advance!

2 Answers

Recoil.JS is meant to be used with react hooks, I don't think they provide any other functions other than hooks. If you can't change Login.js to a functional component try using a wrapping functional component that passes the token as prop to the login.js component.

I'd suggest useRecoilState(myAtom).

function LoginWrapper(props) {
    const [token, setToken] = useRecoilState(myAtom);

    useEffect(() => {
      async function get() {
         const { data: { token: jwt } } = await APIS.login(apiRoute,requestObject);

         setToken(jwt);
      }

      get();
    }, []);

    return <LoginComponent {...props} jwt={token} />
}

As @Matt said, you must wrap your class component into a functional one that passes the Recoil APIs as a prop.

Anyway, if you want to set the atom' token from your Login component, you could simply wrap Login into a component that passes down the result of useSetRecoilState

const LoginWrapper = () => {
  const setToken = useSetRecoilState(tokenState);
  return <Login setToken={setToken} />;
};

In case of more complex cases, you could leverage Recoil' useRecoilCallback that allows you to consume the whole Recoil APIs at once

const LoginWrapper = () => {
  const setToken = useRecoilCallback(({ set }) => token => {
    set(tokenState, token);
  });

  return <Login setToken={setToken} />;
};

Please note: the main difference between using setRecoilState and setRecoilCallback is that using setRecoilState automatically subscribes the consuming component to the atom changes, while setRecoilCallback does not subscribe it so you could avoid some renders.

You can find both the solutions in this working CodeSandbox. As you can see the PrintToken component re-renders correctly as soon as the Login component updates the token.

Let me know if you need more help

Related