验证引用的正确使用,渲染过程中是否进行读写操作。请参阅 useRef()
用法 中的 “pitfalls” 部分。
¥Validates correct usage of refs, not reading/writing during render. See the “pitfalls” section in useRef()
usage.
规则详情
¥Rule Details
引用保存的值不会用于渲染。与状态不同,更改引用不会触发重新渲染。在渲染过程中读取或写入 ref.current
会破坏 React 的预期。当你尝试读取引用时,它们可能尚未初始化,并且它们的值可能过时或不一致。
¥Refs hold values that aren’t used for rendering. Unlike state, changing a ref doesn’t trigger a re-render. Reading or writing ref.current
during render breaks React’s expectations. Refs might not be initialized when you try to read them, and their values can be stale or inconsistent.
如何检测引用
¥How It Detects Refs
lint 仅将这些规则应用于它知道是引用的值。当编译器看到以下任何一种模式时,会将值推断为 ref:
¥The lint only applies these rules to values it knows are refs. A value is inferred as a ref when the compiler sees any of the following patterns:
-
从
useRef()
或React.createRef()
返回。¥Returned from
useRef()
orReact.createRef()
.const scrollRef = useRef(null); -
名为
ref
或以Ref
结尾的标识符,用于读取或写入.current
。¥An identifier named
ref
or ending inRef
that reads from or writes to.current
.buttonRef.current = node; -
通过 JSX
ref
prop(例如<div ref={someRef} />
)传递。¥Passed through a JSX
ref
prop (for example<div ref={someRef} />
).<input ref={inputRef} />
一旦某个对象被标记为 ref,该推断就会通过赋值、解构或辅助函数调用来跟踪该值。即使在另一个接收引用作为参数的函数中访问 ref.current
,这也会允许 lint 检测违规行为。
¥Once something is marked as a ref, that inference follows the value through assignments, destructuring, or helper calls. This lets the lint surface violations even when ref.current
is accessed inside another function that received the ref as an argument.
常见违规
¥Common Violations
-
渲染过程中读取
ref.current
¥Reading
ref.current
during render -
渲染过程中更新
refs
¥Updating
refs
during render -
使用
refs
来处理应为状态的值¥Using
refs
for values that should be state
无效
¥Invalid
此规则的错误代码示例:
¥Examples of incorrect code for this rule:
// ❌ Reading ref during render
function Component() {
const ref = useRef(0);
const value = ref.current; // Don't read during render
return <div>{value}</div>;
}
// ❌ Modifying ref during render
function Component({value}) {
const ref = useRef(null);
ref.current = value; // Don't modify during render
return <div />;
}
有效
¥Valid
此规则的正确代码示例:
¥Examples of correct code for this rule:
// ✅ Read ref in effects/handlers
function Component() {
const ref = useRef(null);
useEffect(() => {
if (ref.current) {
console.log(ref.current.offsetWidth); // OK in effect
}
});
return <div ref={ref} />;
}
// ✅ Use state for UI values
function Component() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}
// ✅ Lazy initialization of ref value
function Component() {
const ref = useRef(null);
// Initialize only once on first use
if (ref.current === null) {
ref.current = expensiveComputation(); // OK - lazy initialization
}
const handleClick = () => {
console.log(ref.current); // Use the initialized value
};
return <button onClick={handleClick}>Click</button>;
}
故障排除
¥Troubleshooting
代码检查结果将我的普通对象标记为 .current
¥The lint flagged my plain object with .current
name heuristic 故意将 ref.current
和 fooRef.current
视为真正的引用。如果你正在建模自定义容器对象,请选择其他名称(例如 box
)或将可变值移入状态。重命名可以避免 lint 检查,因为编译器不再将其推断为引用。
¥The name heuristic intentionally treats ref.current
and fooRef.current
as real refs. If you’re modeling a custom container object, pick a different name (for example, box
) or move the mutable value into state. Renaming avoids the lint because the compiler stops inferring it as a ref.