Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use AuthContext inside of a class component?

I have an auth-context.js file that looks like this following:

import React, { createContext, useState } from "react";

const AuthContext = createContext({});

const AuthProvider = (props) => {
  const [loggedIn, setLoggedIn] = useState(false);

  const login = () => {
    setLoggedIn(true);
  };

  const logout = () => {
    setLoggedIn(false);
  };

  const authContextValue = {
    login,
    loggedIn,
    logout,
  };
  return <AuthContext.Provider value={authContextValue} {...props} />;
};

const useAuth = () => React.useContext(AuthContext);

export { AuthProvider, useAuth };

I am trying to use this to set up authorization, but I am unable to get it to work because this is a function and I need to use it in a class component.

This is how I tried using it in the class component:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { useAuth } from "../auth-context";

// the below is used when a user clicks login
const { login } = useAuth();
login();

This is the error I get:

Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

So how can I use AuthContext? Does it need to be converted to a class component or something else?

This is my index.js file:

ReactDOM.render(
  <React.StrictMode>
    <AuthProvider>
      <App />
    </AuthProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

And my App.jsfile:

function App() {
  const { loggedIn } = useAuth();
  console.log("Is Logged in: " + loggedIn);

  return (
    <Fragment>
      <Router>
        <HeaderComponent />
        <Routes>
          <Route path="/login" element={<Login />}></Route>
          <Route path="/register" element={<Register />}></Route>
          <Route path="/" element={<LandingPage />}></Route>
        </Routes>
        <FooterComponent />
      </Router>
    </Fragment>
  );
}

export default App;

>Solution :

Option 1 – create a new component that wraps the Login component, and use Context.Consumer, and pass the context values via the props:

const WrappedLogin = () => (    
  <AuthContext.Consumer>
    {authProps => <Login {...authProps} />}
  </AuthContext.Consumer>
)

In the auth-context.js file export AuthContext as well, so you can import it:

export { AuthProvider, useAuth, AuthContext };

Option 2 – create a new component that wraps the Login component, and use useAuth to get props, and pass them to the Login component:

const WrappedLogin = () => {
  const authProps = useAuth();

  return <Login {...authProps} />
}

With options 1 & 2, you’ll get the AuthContext values via the props:

class Login extends React.Component {
  render() {
    const { isLoggedIn } = this.props;
  }
}

Option 3 – If this is the only context that the component is going to consume, you can use contextType. In this case you can consume your AuthContext values via this.context:

class Login extends React.Component {
  render() {
    const { isLoggedIn } = this.context;
  }
}
Login.contextType = AuthContext;

In the auth-context.js file export AuthContext as well, so you can import it:

export { AuthProvider, useAuth, AuthContext };
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading