useContext仅在无状态功能组件中工作

时间:2019-02-14 17:19:09

标签: javascript reactjs

我正在努力掌握React中新的useContext函数。在无状态功能组件中非常有效。例如:

import React from 'react';
import LocaleContext from '../LocaleContext';

const Link = ({ text, url }) => {
  const locale = useContext(LocaleContext);

  return (
    <a href={`/${locale}/${url}`}>
      {text}
    </a>
  );
};

export default Link;

我也想在有状态组件甚至非React函数中使用useContext,但是当我这样做时,出现以下错误:

Hooks can only be called inside the body of a function component.

该消息似乎很容易理解,但这是真的吗?我只能在无状态功能组件中使用它吗?如果是这样,对我来说似乎毫无意义,因为使用简单的HOC或传统方法超级简单:

<Locale Consumer>
  {locale => (
    ...
  )}
</LocaleConsumer>

那么这里有什么呢?我的项目中有每个软件包的最新版本。不确定是否重要,但是我正在这里开发NextJS网站。

3 个答案:

答案 0 :(得分:4)

问题是错误所指示的内容。 React钩子在类组件中不可用。由于类组件和功能组件之间存在差异,因此挂钩不能与前者一起使用。

正如the documentation所说,

  

钩子使您无需类即可使用React的更多功能。从概念上讲,React组件始终更接近功能。钩子包含功能,但不影响React的实践精神。钩子可以访问命令式逃生舱门,并且不需要学习复杂的功能或反应性编程技术。

挂钩应该解决特定于类组件的常见用例,而这些类以前是无法单独使用无状态功能组件实现的。自从React 16.8起,功能组件就不是无状态的,它们被允许具有状态并触发自己的更新。

关于useContext hook

  

提供程序更新时,此挂钩将触发使用最新上下文值的重新呈现。

由于功能组件和类组件之间的差异,在类组件中会造成混乱。每次渲染组件时都会调用组件函数:

const Foo = props => {

  const context = useContext(Context);
  // use context
}

除了render函数之外,类组件中没有其他位置会表现相同的行为。而且,如果特定于生命周期的任务转到render函数,则意味着类是错误的选择,并且需要将类组件重构为函数。

类组件中与useContext相对的是contextType,目前仅限于单个上下文。

答案 1 :(得分:2)

如果您真的想使用类(我实际上来自Angular并且仍然喜欢使用类),则可以这样轻松地解决:

class ComponentImpl extends React.Component<any> {
  constructor(props?) {
    super(props);
  }

  render() {
    return (
      <div>
        CounterButton: <button onClick={() => {this.props.appContext.setCount(this.props.appContext.count + 5)}}>App Counter + 5</button>
      </div>
    )
  }
}

export function Component() {
  let appContext = useContext(AppContext);

  return <ComponentImpl appContext={appContext}></ComponentImpl>
};

您只需使用它:<Component></Component>

答案 2 :(得分:0)

useContext是一个钩子,它使用上下文,并且只能在功能组件中使用。

如果您想在类组件中使用上下文,则需要查看其他方法,例如Consumer Component,official docs for this here

来源:How to use useContext in functional components?