Using extended classes for props doesn't get picked up by react-refresh
See original GitHub issueI have a curious case where I am using classes instead of plain old JS objects as input properties for my components.
Simple usage with classes like the following works as expected and maintains its state when I make changes to styling etc.
import { createElement, useState } from 'react'
export class CounterProps {
constructor(title) {
this.title = title;
}
}
export const Counter = (props) => {
const [count, setCount] = useState(0)
return createElement("div", null,
createElement("h1", null, props.title),
createElement("h1", null, count),
createElement("button", { onClick: () => setCount(count + 1) }, "Increment")
);
}
export const Counters = () => {
return createElement("div", null,
createElement(Counter, new CounterProps("Page title")),
createElement(Counter, new CounterProps("Another title"))
);
}
However, once I extend CounterProps
with anything then fast-refresh doesn’t pick up the changes anymore:
export class Anything { }
export class CounterProps extends Anything {
constructor(title) {
super();
this.title = title;
}
}
I am using the following versions (on Windows):
- react-refresh v0.9.0
- @pmmmwh/react-refresh-webpack-plugin v0.4.3
- react v16.14.0
- webpack v4.44.2
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:22 (7 by maintainers)
Top Results From Across the Web
React.Component
Use shouldComponentUpdate() to let React know if a component's output is not affected by the current change in state or props. The default...
Read more >React: why child component doesn't update when prop changes
Update the child to have the attribute 'key' equal to the name. The component will re-render every time the key changes.
Read more >How To Manage State on React Class Components
To update state , React developers use a special method called setState that is inherited from the base Component class. The setState method...
Read more >React Class Components - W3Schools
Props. Another way of handling component properties is by using props . · Props in the Constructor. If your component has a constructor...
Read more >Why hooks are the best thing to happen to React
Originally, React mainly used class components, which can be strenuous ... export default class Hello extends Component { constructor(props) ...
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 FreeTop 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
Top GitHub Comments
@gaearon The reason is simple: this is how F# records are compiled to JavaScript using Fable and these F# records happen to be a really nice way to define lightweight React component prop types:
There are workarounds of course but I would really appreciate it if we could define React components in F# the following structure: F# source file is called {ComponentName}.fs and contains the props type definition along with the function itself. Potentially having multiple small components and their prop types in the same file when you have small components.
Hi @pmmmwh, first of all, thanks a lot for the detailed answer. I now understand why the refresh fails. However, from the perspective of the F# side of things (because I am really talking about JS which is transpiled from F#), it could be possible to add metadata to the class declaration which could very well easily allow fast-refresh to pick it up. Two questions arise:
Which metadata do you need? It could be a dummy, compiler-generated function with a special name like
$IamClass
which will be returned in the property names array when you askObject.getOwnPropertyNames(Test.prototype) => ["constructor", "$IamClass"]
How to generically tell or hint the plugin that with that information? An option passed to the plugin would do the trick
{ classDetectionHints: ["$IamClass"] }
or something similar.What do you think?