如何使用 React js 中的上下文将函数从 FUNCTIONAL 传递给 CLASS 组件并在渲染之外(没有 prop)访问它?

Posted

技术标签:

【中文标题】如何使用 React js 中的上下文将函数从 FUNCTIONAL 传递给 CLASS 组件并在渲染之外(没有 prop)访问它?【英文标题】:How to pass function from FUNCTIONAL to CLASS component and access it outside of render( without prop ), using context in react js? 【发布时间】:2020-08-22 00:09:13 【问题描述】:

如何使用 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

功能组件:

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;

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

【问题讨论】:

【参考方案1】:

在@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;

【讨论】:

【参考方案2】:

从类组件访问 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;

【讨论】:

谢谢。我刚刚运行了您的代码,几乎没问题。我做了一些更改,并将回答工作代码。

以上是关于如何使用 React js 中的上下文将函数从 FUNCTIONAL 传递给 CLASS 组件并在渲染之外(没有 prop)访问它?的主要内容,如果未能解决你的问题,请参考以下文章

React - 如何使用上下文从对象中应用多个值

魔法? React 上下文提供者从何而来?命名约定?

如何将 React 中的状态从一个类传递到另一个类?

从 React JS 中的输入字段获取值

如何将参数传递给 React js 中的函数?

如何将地理位置 lat lng 从函数传递到 React 中另一个函数的“ll”属性?