Как передать функцию из ФУНКЦИОНАЛЬНОГО в компонент КЛАССА и получить к нему доступ вне рендеринга (без опоры), используя контекст в React js?

Как я могу передать функцию из ФУНКЦИОНАЛЬНОГО в компонент КЛАССА, используя контекст в react js?

Мой код:

КОНТЕКСТ:

authContext.js

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

ФУНКЦИОНАЛЬНЫЙ компонент:

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;

Компонент КЛАСС:

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;

Используя функцию setAuth из AuthForm.js (компонент класса), я хочу изменить значение isAuthenticated в App.js (функциональный компонент). Итак, в основном я хочу получить доступ к setAuth в componentDidUpdate ().




Ответы (2)


Решил проблему с помощью @gemhar

Изменения, которые необходимо внести в 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;
person Nafeo Joy    schedule 07.05.2020

Наиболее распространенный способ доступа к Context из компонента класса - через static contextType. Если вам нужно значение из контекста вне рендеринга или в методе жизненного цикла, вы можете использовать его таким образом.

import React from "react";
import AuthContext from "./context";

class AuthForm extends React.Component {
  constructor(props) {
      ...
  }
  static contextType = AuthContext

  componentDidUpdate() {
    const {setAuth} = this.context
    // Access the 'setAuth' function here
  }

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

export default AuthForm;
person gemhar    schedule 06.05.2020
comment
Спасибо. Я только что запустил ваш код, и он почти в порядке. Внес некоторые изменения и отвечу на рабочий код. - person Nafeo Joy; 07.05.2020