首页 > 解决方案 > 从 Children's Method 访问 React Context API 的方法

问题描述

我是 React 的新手,正在尝试制作上下文 API。我已经阅读了一些类似的问题,但我无法得到解决方案。

我的上下文提供程序文件:

import React, { Component } from 'react'

    const MyContext = React.createContext();

    class ContextProvider extends Component {

        constructor(props) {
          super(props)

            this.state = {
               isLogin: false
            }   
        }  

        handleLogin = () => {   
          this.setState({
              isLogin : true
          })              
        }


      render() {
        return (    
          <MyContext.Provider value={{
              ...this.state,
              handleLogin : this.handleLogin
              }}>
             {this.props.children}
          </MyContext.Provider>
        );
      }
    }

    const ContextConsumer = MyContext.Consumer;
    export {ContextProvider, ContextConsumer};

用户成功登录后,我需要通过访问 ContextProvider.js 中的 handleLogin() 来更改状态:

import React, { Component } from 'react'
import {ContextConsumer} from "./ContextProvider";

class Login extends Component {

  onHandleSubmit = () => {

    // on submit login success :

    // --- how to call handleLogin() in ContextProvider.js here ? ----

  }

  render() { 
      return (
        <div> --- not expected here ---- </div>
     )
  }

} 

顺便说一句,对不起我的英语。

标签: reactjsreact-context

解决方案


假设您的 Login 组件由ContextProvider层次结构中的较高层包装,您可以通过定义静态 contextType 来访问类组件内的上下文。

为此,您需要首先从 ContextProvider 导出上下文,例如

export {ContextProvider, ContextConsumer, MyContext };

然后像这样使用它

import React, { Component } from 'react'
import {MyContext} from "./ContextProvider";
class Login extends Component {

  static contextType = MyContext;
  onHandleSubmit = () => {

    // on submit login success :

    this.context.handleLogin();

  }

  render() { 
      return (
        <div> {/* render content here */} </div>
     )
  }

} 

但是,如果您使用的是 16.3.0 和 16.6.0 之间的 react 版本,则需要使用渲染道具模式传递上下文,例如

class Login extends Component {

  onHandleSubmit = () => {

    // on submit login success :

    this.props.context.handleLogin();

  }

  render() { 
      return (
        <div> --- not expected here ---- </div>
     )
  }

} 

export default (props) => (
    <ContextConsumer>
        {values=> <Login {...props} context={values} />}
    </ContextConsumer>
)

推荐阅读