Appearance
eslint 插件
eslint-plugin-react-hooks-ref
- 强制要求 useRef 的变量必须用
const
声明且以Ref
结尾,并且能够自动修复
插件实现
js
// plugins/eslint-plugin-react-hooks-ref.js
export default {
rules: {
// 规则名称
"enforce-ref-naming": {
meta: {
type: "problem",
docs: {
description:
"强制要求 useRef 的变量必须用 const 声明且以 Ref 结尾,并确保正确使用 .current",
recommended: true,
},
fixable: "code",
schema: [],
hasSuggestions: true,
},
create(context) {
// 存储所有 useRef 变量名
const refVariables = new Set();
return {
// 检查变量声明
VariableDeclarator(node) {
const isUseRefCall =
node.init &&
node.init.type === "CallExpression" &&
node.init.callee.name === "useRef";
if (isUseRefCall && node.id.type === "Identifier") {
const varName = node.id.name;
refVariables.add(varName);
// 检查 const 声明
if (node.parent.kind !== "const") {
context.report({
node: node.parent,
message: "useRef 的变量必须用 const 声明",
fix(fixer) {
return fixer.replaceTextRange(
[
node.parent.start,
node.parent.start + node.parent.kind.length,
],
"const"
);
},
});
}
// 检查变量名后缀
if (!varName.endsWith("Ref")) {
context.report({
node: node.id,
message: "useRef 的变量名必须以 Ref 结尾",
fix(fixer) {
return fixer.insertTextAfter(node.id, "Ref");
},
});
}
}
},
// 检查 MemberExpression (如 a.current)
MemberExpression(node) {
if (
node.property.type === "Identifier" &&
node.property.name === "current" &&
node.object.type === "Identifier"
) {
const objectName = node.object.name;
if (!refVariables.has(objectName) && objectName.endsWith("Ref")) {
context.report({
node,
message: `使用 ${objectName} 时应该用 ${objectName.replace(
"Ref",
""
)}.current`,
fix(fixer) {
return fixer.replaceText(
node.object,
objectName.replace("Ref", "")
);
},
});
} else if (
!objectName.endsWith("Ref") &&
refVariables.has(objectName + "Ref")
) {
context.report({
node,
message: `使用 ${objectName}.current 时应该用 ${objectName}Ref.current`,
fix(fixer) {
return fixer.replaceText(node.object, `${objectName}Ref`);
},
});
}
}
},
};
},
},
},
};
引用插件
js
// eslint.config.js
import reactHooksRef from "./plugins/eslint-plugin-react-hooks-ref.js";
export default [
// ...其他配置
plugins: {
"react-hooks-ref": reactHooksRef, // 加载自定义插件
},
rules: {
"react-hooks-ref/enforce-ref-naming": "error", // 启用规则,违反时报错
},
];