Bug: useState with class as initial state throws an error
See original GitHub issueUsing a JavaScript class as initial state in useState
throws an error. This is because mountState
check if the initial state is a function by typeof initialState === 'function'
and classes are technically functions. However since ES6+, I feel like most developers don’t consider classes functions because of the less prototype-inheritance feel since ES6 and the class
keyword.
React version: 17.0.2
Steps To Reproduce
- Define an ES6 class
- Use the class as
initialState
argument touseState
Code example:
import { useState } from "react";
import ReactDOM from "react-dom";
class A {}
function App() {
const [cls, setCls] = useState(A);
return <h2>{cls.name}</h2>;
}
ReactDOM.render(<App />, document.body);
The current behavior
TypeError: Cannot call a class as a function
at _classCallCheck (eval at z (eval.js:42), <anonymous>:3:11)
at A (VM302 index.js:19)
at mountState (react-dom.development.js:10436)
at Object.useState (react-dom.development.js:10919)
at useState (react.development.js:954)
at App (VM302 index.js:25)
Alternatively, the error can be TypeError: Class constructor X cannot be invoked without 'new'
.
The expected behavior
As mentioned in the description above, I would
- either expect classes to work
- or mention this caveat in the docs.
I guess checking, if the initial state is actually a non-class function, could cause instances of subclasses of functions not to work (depending how the check is done).
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
5 Most Common useState Mistakes React Developers Often ...
The problem is that useState allows you to define its initial state using anything you want.
Read more >Why does setState callback throw an error: "State updates ...
1 Answer 1 · Tried that. Error: React Hook "useEffect" cannot be called inside a callback. React Hooks must be called in a...
Read more >React Hooks cheat sheet: Best practices with examples
Declaring a state variable is as simple as calling useState with some initial state value, like so: useState(initialStateValue) . const ...
Read more >Hooks FAQ - React
They let you use state and other React features without writing a class. ... classes to Hooks unless you planned to rewrite them...
Read more >react-hydration-error - Next.js
function MyComponent() { // This condition depends on `window`. ... useState } from 'react' function MyComponent() { // The default value is 'blue', ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I’d like to see a PR that warns if setState or useState is passed a function whose first letter is capital. That’s enough of a hint to find the common cases.
I don’t consider this a bug.
As the issue description mentions,
useState
supports two formats:useState('value')
)useState(() => 'value')
)React decides which one you’ve done using the
typeof
operator. (I am not aware of an alternative to this approach but please feel free to share one if you have an idea.)In JavaScript, the
typeof
a class is"function"
so React thinks you’re using the second format and tries to call the “function” which causes an error to be thrown. To fix this, you can wrap your class value with a function, like so:I’ll tag this as a discussion for now, but I’m not sure this is something that we’ll change.