ArnaudBarre / eslint-plugin-react-refresh

Validate that your components can safely be updated with Fast Refresh
MIT License
216 stars 14 forks source link

Possible false-positive with memo default export #27

Closed silverwind closed 1 year ago

silverwind commented 1 year ago
import {memo} from "react";

export default memo(function Foo() {
  return <div/>;
})

Results in

  4:16  error  Fast refresh can't handle anonymous components. Add a name to your export  react-refresh/only-export-components

As far as I'm aware this is still a named component because of the function name and the module is asking for something impossible because a default export can not be named.

(The reason this can not be changed to a named export is because lazy requires a default export).

ArnaudBarre commented 1 year ago

The solution is to write:

import {memo} from "react";

const MemoFoo = memo(function Foo() {
  return <div/>;
});
MemoFoo.displayName = "MemoFoo";
export default MemoFoo;

This is a bot verbose I agree but it's more imposed by the React team to improve naming inside the react devtool and stacktraces. I need to verify the difference in reality, and maybe it could be optional for some cases because this pattern actually fast-refresh correctly at runtime.

silverwind commented 1 year ago

As far as I'm aware in regards to DevTools, displayName is not necessary if it's a named function statement like above because DevTools can just access function.prototype.name.

The export default with the variable should work as far as the linter is concerned, thought I don't particularily like this verbosity :)

ArnaudBarre commented 1 year ago

Fixed, will released later this week when other issues are handled!

ArnaudBarre commented 1 year ago

Released in v0.4.4!