2

如何使用 React js 中的上下文将函数从 FUNCTIONAL 传递给 CLASS 组件?

我的代码:

语境:

authContext.js

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

功能组件:

应用程序.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;

使用 AuthForm.js(类组件)中的 setAuth 函数,我想更改 App.js(功能组件)中 isAuthenticated 的值。 所以,基本上我想在 componentDidUpdate() 中访问 setAuth。

4

2 回答 2

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;
于 2020-05-07T11:51:31.940 回答
1

从类组件访问 Context 的最常见方法是通过静态 contextType。如果您在渲染之外或在生命周期方法中需要来自 Context 的值,您将使用这种方式。

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;
于 2020-05-06T22:44:30.843 回答