Custom Rules
Function Component Definition
Enforce function components to be defined with arrow functions.
Rule Code
Copy and paste this into your eslint.config.ts:
import eslintJs from "@eslint/js";
import { defineConfig as defineReactConfig, merge } from "@eslint-react/kit";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(
{
files: ["**/*.{ts,tsx}"],
extends: [
eslintJs.configs.recommended,
tseslint.configs.recommended,
defineReactConfig(
{
name: "function-component-definition",
make: (ctx, kit) => {
const { query, visitor } = kit.collect.components(ctx);
return merge(
visitor,
{
"Program:exit"(program) {
for (const { node } of query.all(program)) {
if (node.type === "ArrowFunctionExpression") continue;
ctx.report({
node,
message: "Function components must be defined with arrow functions.",
});
}
},
},
);
},
},
),
],
},
);Examples
❌ Invalid
// Function declaration
function MyComponent() {
return <div>Hello</div>;
}
// Function expression
const MyComponent = function() {
return <div>Hello</div>;
};✅ Valid
// Arrow function
const MyComponent = () => {
return <div>Hello</div>;
};
// Arrow function with implicit return
const MyComponent = () => <div>Hello</div>;How It Works
This rule uses kit.collect.components to identify all React function components in the file. It then checks if each component is defined using an ArrowFunctionExpression. If a component uses a function declaration or expression instead, it reports an error.
Common Use Cases
| Scenario | Recommendation |
|---|---|
| Consistent syntax | Enforce arrow functions across all components |
| Named exports | Allow function declarations for named exports only (customize the rule) |
| Object methods | Treat object methods as components with custom hint |
Customization Ideas
- Change the rule to enforce function declarations instead of arrow functions
- Add auto-fix to convert function declarations to arrow functions
- Add suggestions to convert function components between different definition styles
- Check whether a component is wrapped in
memoorforwardRefusingkit.flag.component.Memo/kit.flag.component.ForwardRef - Exclude memoized components by inspecting
component.flag & kit.flag.component.Memo