获取无效的挂钩调用挂钩只能在具有 SharePoint 框架模板的函数组件的主体内调用

Getting Invalid hook call Hooks can only be called inside of the body of a function component with SharePoint Framework Template

我明白了

sp-webpart-workbench-assembly_default.js:26401 [1599066762186][OtherGlobalError.window.onerro] Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

重现步骤

md helloworld-webpart2
cd helloworld-webpart2
yo @microsoft/sharepoint
(select SP Online latest, React)
(modify code like below, add the 1 line of code to add the hook) (helloworld-webpart2\src\webparts\helloWorld\components\HelloWorld.tsx)
gulp serve

环境

Windows 10
SharePoint Online
Node v10
Chrome v79
VS Code | SPFx v1.10.0 

代码

import * as React from 'react';
import styles from './HelloWorld.module.scss';
import { IHelloWorldProps } from './IHelloWorldProps';
import { escape } from '@microsoft/sp-lodash-subset';

export default class HelloWorld extends React.Component<IHelloWorldProps, {}> {
  public render(): React.ReactElement<IHelloWorldProps> {
    const [count, setCount] = React.useState(0); // THIS LINE CAUSES HOOK ISSUE <-----------------
    return (
      <div className={ styles.helloWorld }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <span className={ styles.title }>Welcome to SharePoint!</span>
              <p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
              <p className={ styles.description }>{escape(this.props.description)}</p>
              <a href="https://aka.ms/spfx" className={ styles.button }>
                <span className={ styles.label }>Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

如果我用钩子删除那条线,那么它就可以了。

有谁知道哪里出了问题吗?

您需要使用功能组件而不是 class。功能组件只是一个功能。它应该看起来像这样:

const HelloWorld : React.FC<IHelloWorldProps> = (props : IHelloWorldProps) => {
    const [count, setCount] = React.useState(0);

    return (
      <div className={ styles.helloWorld }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <span className={ styles.title }>Welcome to SharePoint!</span>
              <p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
              <p className={ styles.description }>{escape(props.description)}</p>
              <a href="https://aka.ms/spfx" className={ styles.button }>
                <span className={ styles.label }>Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default HelloWorld;