如何在旧版React组件及使用旧ref回调API的组件中使用useRef?
Hey there! Let's break down your two questions about React refs and Hooks clearly:
问题1:如何在旧版React组件(类组件)中使用useRef?
First off, a quick clarification: useRef is a React Hook API, and Hooks only work in function components or custom Hooks. That means you can't directly use useRef in old-style class components.
If you need to grab a reference to a DOM element or component instance in a class component, use React.createRef() instead:
import React from 'react'; class OldClassComponent extends React.Component { constructor(props) { super(props); // 创建ref对象 this.inputRef = React.createRef(); } componentDidMount() { // 通过current属性访问引用 this.inputRef.current.focus(); } render() { return <input ref={this.inputRef} />; } }
如果你的类组件之前已经在使用回调ref模式(也就是你示例里的ref={r => ...}写法),也可以继续沿用——它和createRef作用一致,只是语法不同:
class OldClassComponent extends React.Component { constructor(props) { super(props); this.inputRef = null; this.setInputRef = (element) => { this.inputRef = element; }; } componentDidMount() { if (this.inputRef) { this.inputRef.focus(); } } render() { return <input ref={this.setInputRef} />; } }
问题2:如何为采用旧ref回调API的组件使用useRef?
看你提供的示例,App是函数组件,里面的Input子组件使用了回调形式的ref。要通过useRef保存这个引用,只需要在回调函数里把传入的实例/元素赋值给useRef创建的对象的current属性即可:
import React, { useRef, useEffect } from 'react'; import { Input, Button } from 'antd'; const App = () => { // 创建useRef对象 const inputRef = useRef(null); useEffect(() => { // 组件挂载后,就可以通过inputRef.current访问Input实例 if (inputRef.current) { console.log('Input实例:', inputRef.current); // 比如调用Input的focus方法 inputRef.current.focus(); } }, []); return ( <div> {/* 在回调里更新ref的current值 */} <Input ref={(r) => (inputRef.current = r)} /> <Button type="primary">Hello</Button> </div> ); };
核心逻辑是:当Input组件挂载时,它的ref回调会传入组件实例(或DOM元素),我们把这个值存入inputRef.current,这样就能在函数组件的任何位置(比如useEffect、事件处理函数)访问这个引用了。
如果原来的回调ref里还有其他逻辑(比如你示例中的console.log(r)),记得把它保留下来:
<Input ref={(r) => { console.log(r); inputRef.current = r; }} />
这样既保留了原有的日志逻辑,又把引用保存到了useRef对象中。
内容的提问来源于stack exchange,提问作者user3106579

