react中如何合理使用ref
使用场景
React中的ref用于直接访问DOM节点或React组件实例。常见场景包括管理焦点、触发动画、集成第三方DOM库等。避免过度使用ref,优先考虑通过props和state管理组件行为。
创建ref
在函数组件中使用useRef Hook创建ref,类组件中使用React.createRef()。ref对象包含一个current属性,初始值为null,后续指向具体的DOM节点或组件实例。

// 函数组件
const inputRef = useRef(null);
// 类组件
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
}
绑定ref
通过ref属性将ref对象绑定到DOM元素或类组件上。函数组件默认不支持ref绑定,需使用forwardRef转发。
// 绑定DOM元素
<input ref={inputRef} />
// 转发ref到函数组件
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="fancy">
{props.children}
</button>
));
访问ref
通过ref对象的current属性访问绑定的节点或实例。注意在组件挂载完成后才能访问,避免在渲染阶段直接操作ref。

useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
回调ref
作为ref属性的替代方案,传递一个函数接收DOM节点或组件实例。函数会在组件挂载和卸载时调用,参数分别为节点实例或null。
<input ref={(node) => {
// node为DOM元素或null
}} />
性能优化
避免在渲染过程中修改ref或创建新的ref回调函数,这可能导致不必要的重新渲染。对于回调ref,推荐定义为实例方法(类组件)或使用useCallback(函数组件)。
const refCallback = useCallback((node) => {
// 处理节点
}, []);
注意事项
ref不会触发组件重新渲染,修改ref的current属性也不会导致更新。避免将ref用于声明性操作,优先考虑通过state控制。函数组件内部使用ref时,需结合useEffect或useLayoutEffect处理副作用。






