question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: useState inside pure JavaScript/TypeScript class violates rules of hooks

See original GitHub issue

React version: 18.x

Steps To Reproduce

  1. use the following code in React project
  2. see a compilation error

Link to code example:

class ThemeService {
  private _theme: any;
  private _setTheme: any;
  constructor() {
    const [theme, setTheme] = useState("Red");
    this._theme = theme;
    this._setTheme = setTheme;
  }

  get theme(): string {
    return this._theme;
  }

  ToggleTheme() {
    this._setTheme(this._theme === "Red" ? "Blue" : "Red");
  }
}

The current behavior

above usage generates the following compilation error

ERROR in [eslint] src/App.tsx Line 8:31: React Hook “useState” cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function

The expected behavior

I understand that the class Component has diff state management so “useState” is not allowed inside the class-based react component but I am not sure why usage inside the pure class is restricted.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
pashvincommented, Aug 12, 2022

Thanks for the detail and for the video which explains closers. After looking into “closers video”, I thought my code is working because I am creating a singleton and it will break and mess up with the internal state as soon as I create two instances like the following but surprisingly it works so I don’t know why we want to break which is working and looks like the answer is the design decision to avoid classes for simplicity. I have intermediate-level knowledge of React and can’t argue much against the decision but hope if this is supported, then can open a door for diff pattern.

class CounterLogic {
  constructor() {
    // eslint-disable-next-line
    const [count, setCount] = React.useState(10);
    this._count = count;
    this._setCount = setCount;
  }

  count() {
    return this._count;
  }

  inc() {
    this._setCount(this._count + 1);
  }

  dec() {
    this._setCount(this._count - 1);
  }
}

const Counter = () => {
  const test = new CounterLogic();

  return (
    <div>
      <h2>Counter: {test.count()}</h2>
      <button onClick={()=>test.inc()}>Increment</button>
      <button onClick={()=>test.dec()}>Decrement</button>
    </div>
  );
}

const App = () => {

  return (
    <div>
      <Counter/>
      <Counter/>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
0reactions
rickhanloniicommented, Aug 26, 2022

Closing, as @markerikson explained, hooks are not intended to work inside classes and we don’t think making them work there is the right approach.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Hook "useState" cannot be called in a class component ...
The state hook (useState) is available with functional React Components, but in your case you are using a Class component.
Read more >
The noob's guide to useState - LogRocket Blog
Using React Hooks, like useState, allows you to ditch class-based components, but are you cultivating bad practice? Find out here.
Read more >
Update boolean state right with React Hooks
First things first – useCallback does nothing in this implementation. Unless a dependencies array is passed as a second parameter, useCallback ...
Read more >
Solving React Hooks' invalid hook call warning - Rob Kendal
Building a React project and have the error 'Hooks can only be called inside the body of a function component'? We'll solve the...
Read more >
Hooks Pattern - Patterns.dev
React provides a hook that manages state within a functional component, called useState . Let's see how a class component can be restructured...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found