繁体   English   中英

React useContext throws无效的钩子调用错误

[英]React useContext throws Invalid hook call error

我试图使用useContext将值从上下文提供程序传递给使用者,并访问render函数之外的值。

我的提供商看起来像这样:

export const AppContext = React.createContext();

export class App extends React.Component(){
    render(){
        <AppContext.Provider value={{ name: 'John' }} ><Main /></AppContext>   
    }
}

我的消费者看起来像这样

import React, { useContext } from 'react';
import { AppContext } from './App';

export class Main extends React.Component(){
    componentDidMount(){
        const value = useContext(AppContext);
    }
    render(){
        return (
            <div>Main Component</div>
        )
    }
}

错误是这样的:

钩子调用无效。 钩子只能在函数组件的主体内部调用。


如果你想使用钩子,它们是为功能组件设计的。 像这样:

import React, { useContext } from 'react';
import { AppContext } from './App';

const Main = () => {
  const value = useContext(AppContext);

  return(
    <div>Main Component</div>
  );
}

如果要在基于类的组件中使用它,那么只需在类中将其设置为静态contextType,然后就可以在组件中使用this.context ,如下所示:

import React from 'react';
import { AppContext } from './App';

class Main extends React.Component(){

  static contextType = AppContext;

  componentDidMount(){
    const value = this.context;
  }
  render(){
    return (
      <div>Main Component</div>
    )
  }
}

编辑:从您的应用程序组件中删除您的上下文并将其放在自己的组件中。 我认为您在导出上下文时遇到冲突。

所以你的应用程序组件应如下所示:

import React from "react";
import Context from "./Context";
import Main from "./Main";

class App extends React.Component {
  render() {
    return (
      <Context>
        <Main />
      </Context>
    );
  }
}

export default App;

您的主要组件应该是:

import React from "react";
import { AppContext } from "./Context";

class Main extends React.Component {
  static contextType = AppContext;

  render() {
    return <div>{this.context.name}</div>;
  }
}

export default Main;

你的上下文组件应该像:

import React from "react";

export const AppContext = React.createContext();

class Context extends React.Component {
  state = {
    name: "John"
  };

  //Now you can place all of your logic here
  //instead of cluttering your app component
  //using this components state as your context value
  //allows you to easily write funcitons to change
  //your context just using the native setState 
  //you can also place functions in your context value
  //to call from anywhere in your app
  render() {
    return (
      <AppContext.Provider value={this.state}>
        {this.props.children}
      </AppContext.Provider>
    );
  }
}

export default Context;

这是一个沙箱,向您展示它正在使用CodSandbox

你得到上面的错误,因为Hooks意味着在函数组件内使用而不是类组件,而你试图在main组件的componentDidMount中使用它,它是一个类组件

您可以使用useContext hook重写主组件的代码

import React, { useContext } from 'react';
import { AppContext } from './App';

export const Main =() =>{
    const value = useContext(AppContext);
    return (
        <div>Main Component</div>
    )
}

或者以类似的方式以不同的方式使用Context

import React from 'react';
import { AppContext } from './App';

class Main extends React.Component {
    componentDidMount(){
        const value = this.context;
        // use value here. Also if you want to use context elsewhere in class
        // you can use if from this.context
    }
    render(){
        return (
            <div>Main Component</div>
        )
    }
}

Main.contextType = AppContext;

export { Main };

挂钩仅适用于无状态组件。 您正尝试在类组件中使用它。

这是Main.js文件的内容。 如果要使用基于类的组件而不是功能组件,请取消注释注释的组件。

 import React from "react"; import { AppContext } from "./App"; /** UNCOMMENT TO USE REACT CLASS COMPONENT */ // class Main extends React.Component() { // render() { // return ( // <AppContext.Consumer> // {value => <div>It's Main component. Context value is ${value.name}</div>} // </AppContext.Consumer> // ); // } // } const Main = () => { const value = React.useContext(AppContext); return <div>It's Main component. Context value is ${value.name}</div>; }; export default Main; 

这是App.js文件的内容。 如果要使用基于类的组件而不是功能组件,请取消注释注释的组件。

 import React from "react"; import ReactDOM from "react-dom"; import Main from "./Main"; export const AppContext = React.createContext(); /** UNCOMMENT TO USE REACT CLASS COMPONENT */ // export class App extends React.Component() { // render() { // return ( // <AppContext.Provider value={{ name: "John" }}> // <Main /> // </AppContext.Provider> // ); // } // } const App = () => ( <AppContext.Provider value={{ name: "John" }}> <Main /> </AppContext.Provider> ); const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

React Hooks直接针对功能组件实现,以便为它们提供成为有状态的可能性。 基于类的组件始终是有状态的,因此您必须使用自己的state API。

这里有工作演示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM