I get this

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

Steps to reproduce

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

Environment

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

Code

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>
    );
  }
}

If I remove that line with the hook, then it works.

Does anyone know what is wrong?

1

There are 1 best solutions below

0
On BEST ANSWER

You need to use a functional component and not a class. Functional components are just a function. It should look something like this:

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;