Search code examples
javascriptreactjsreact-contextreact-functional-componentreact-class-based-component

How to pass function from FUNCTIONAL to CLASS component and access it outside of render( without prop ), using context in react js?


How can I pass a function from FUNCTIONAL to CLASS component using context in react js?

My code:

CONTEXT:

authContext.js

import React from 'react'
const AuthContext = React.createContext()
export const AuthProvider = AuthContext.Provider
export const AuthConsumer = AuthContext.Consumer
export default AuthContext

FUNCTIONAL component:

App.js

...
import AuthPage from './pages/AuthPage';
import { AuthProvider } from './components/Context/authContext'

function App(props) {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const checkAuthenticated = async () => {
    //console.time('fetch')

    try {
      const res = await fetch("http://localhost:4000/api/verify", {
        method: "POST",
        headers: { jwt_token: localStorage.token }
      });

      const parseRes = await res.json();
      parseRes === true ? setIsAuthenticated(true) : setIsAuthenticated(false);
    } catch (err) {
      console.error(err.message);
    }
    //console.timeEnd('fetch')

  };

  const setAuth = boolean => {
    setIsAuthenticated(boolean);
  };


  useEffect(() => {
    checkAuthenticated();
  }, [isAuthenticated, setAuth]);


  return (
    <Fragment>
      <BrowserRouter basename={'/'}>
        <GAListener>
          <Switch>
            <LayoutRoute
              exact
              path="/login"
              layout={EmptyLayout}
              component={props => (
                <AuthProvider value={{ setAuth: setAuth }}>
                  <AuthPage {...props} authState={STATE_LOGIN} />
                </AuthProvider>
              )}
            />
            <Redirect to="/" />
          </Switch>
        </GAListener>
      </BrowserRouter>

    </Fragment>
  )
}

export default App;

CLASS component:

AuthForm.js

import AuthContext from '../components/Context/authContext'

class AuthForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      usernameInput: '',
      emailInput: '',
      passwordInput: '',
      confirmPasswordInput: '',
      remeberMe: false,
      agreeTerms: false,
      toDashboard: false
    };
  }

  componentDidMount() {
    if (localStorage.token) {
      this.setState(() => (
        {
          toDashboard: true
        }
      ))
    }
  }
  componentDidUpdate() {
      **// I WANT TO ACCESS THE 'setAuth' function here**
  }

  render() {
    return (
        <div>
            //Some code
        </div>
    );
  }
}

export default AuthForm;

Using setAuth function from AuthForm.js (class component), I want to change the value of isAuthenticated in App.js (functional component). So, basically I want to access setAuth in componentDidUpdate().


Solution

  • Resolved the issue with the help from @gemhar

    Changes to be made in AuthForm.js

    ...
    import AuthContext from '../components/Context/authContext'
    
    class AuthForm extends React.Component {
    
      //Add this line
      static contextType = AuthContext;
    
      constructor(props) {
        super(props);
        this.state = {
          usernameInput: '',
          emailInput: '',
          passwordInput: '',
          confirmPasswordInput: '',
          remeberMe: false,
          agreeTerms: false,
          toDashboard: false
        };
      }
    
      componentDidMount() {
        if (localStorage.token) {
          this.setState(() => (
            {
              toDashboard: true
            }
          ))
        }
      }
      componentDidUpdate() {
          //I can access setAuth here
          this.context.setAuth(true)
    
          //or by destructuring
          let {setAuth} = this.context;
          setAuth(true)
      }
    
      render() {
        return (
            <div>
                //Some code
            </div>
        );
      }
    }
    
    export default AuthForm;