React useContext 抛出 Invalid hook call 错误
React useContext throws Invalid hook call error
我正在尝试使用 useContext
将值从上下文提供者传递给消费者,并在渲染函数之外访问该值。
我的提供商看起来像这样:
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>
)
}
}
错误是这样的:
挂钩调用无效。钩子只能在函数组件的内部调用。
挂钩仅适用于无状态组件。您正在尝试在 class 组件中使用它。
如果你想使用钩子,它们是为函数组件设计的。像这样:
import React, { useContext } from 'react';
import { AppContext } from './App';
const Main = () => {
const value = useContext(AppContext);
return(
<div>Main Component</div>
);
}
如果你想在基于 class 的组件中使用它,那么只需在你的 class 中将它设置为静态 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
这是 Main.js
文件的内容。如果您想使用基于 class 的组件而不是功能组件,请取消注释部分。
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
文件的内容。如果您想使用基于 class 的组件而不是功能组件,请取消注释部分。
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 是直接为功能组件实现的,以便使它们有可能成为有状态的。基于 Class 的组件始终是有状态的,因此您必须使用它们自己的 state
API.
工作演示可用 here。
你得到上面的错误是因为 Hooks 是为了在功能组件内部使用而不是 class 组件,而你试图在 Main 组件的 componentDidMount 中使用它,这是一个 class 组件
您可以使用 useContext 挂钩重写 Main 组件的代码,例如
import React, { useContext } from 'react';
import { AppContext } from './App';
export const Main =() =>{
const value = useContext(AppContext);
return (
<div>Main Component</div>
)
}
或者以不同的方式使用 Context class like
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 };
我正在尝试使用 useContext
将值从上下文提供者传递给消费者,并在渲染函数之外访问该值。
我的提供商看起来像这样:
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>
)
}
}
错误是这样的:
挂钩调用无效。钩子只能在函数组件的内部调用。
挂钩仅适用于无状态组件。您正在尝试在 class 组件中使用它。
如果你想使用钩子,它们是为函数组件设计的。像这样:
import React, { useContext } from 'react';
import { AppContext } from './App';
const Main = () => {
const value = useContext(AppContext);
return(
<div>Main Component</div>
);
}
如果你想在基于 class 的组件中使用它,那么只需在你的 class 中将它设置为静态 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
这是 Main.js
文件的内容。如果您想使用基于 class 的组件而不是功能组件,请取消注释部分。
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
文件的内容。如果您想使用基于 class 的组件而不是功能组件,请取消注释部分。
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 是直接为功能组件实现的,以便使它们有可能成为有状态的。基于 Class 的组件始终是有状态的,因此您必须使用它们自己的 state
API.
工作演示可用 here。
你得到上面的错误是因为 Hooks 是为了在功能组件内部使用而不是 class 组件,而你试图在 Main 组件的 componentDidMount 中使用它,这是一个 class 组件
您可以使用 useContext 挂钩重写 Main 组件的代码,例如
import React, { useContext } from 'react';
import { AppContext } from './App';
export const Main =() =>{
const value = useContext(AppContext);
return (
<div>Main Component</div>
)
}
或者以不同的方式使用 Context class like
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 };