createRef 和 useRef
两种方式登多可以获取页面元素,其中createRef被用于类组件,useRef被用于函数组件。
如果在函数组件中,错误地使用了createRef,函数组件每次更新渲染的时候,都会重新初始化ref的值:参考
import React, { useRef, createRef, useState } from "react";
import ReactDOM from "react-dom";
import { FormInstance } from 'antd/lib/form';
function App() {
const [renderIndex, setRenderIndex] = useState(1);
const refFromUseRef = useRef<FormInstance>();
const refFromCreateRef = createRef<FormInstance>();
if (!refFromUseRef.current) {
console.log('current.set 1', renderIndex);
refFromUseRef?.current = renderIndex;
}
if (!refFromCreateRef.current) {
console.log('current.set 2', renderIndex);
refFromCreateRef?.current = renderIndex;
}
return (
<div className="App">
Current render index: {renderIndex}
<br />
First render index remembered within refFromUseRef.current:
{refFromUseRef.current}
<br />
First render index unsuccessfully remembered within
refFromCreateRef.current:
{refFromCreateRef.current}
<br />
<button onClick={() => setRenderIndex(prev => prev + 1)}>
Cause re-render
</button>
</div>
);
}
export default App;
在TypeScript中,方法中需要传递具体的泛型,又比如下面这个普通的HTML元素
const textRef = useRef<HTMLTextAreaElement>();
return (
<textarea ref={textRef} value={input} placeholder="请输入内容…" onChange={(e) => { setInput(e.target.value); }} />
);
将onChange的回调,从函数声明 改为 函数名后,必须要给事件对象增加类型。
const textRef = useRef<HTMLTextAreaElement>();
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setInput(e.target.value );
}
return (
<textarea ref={textRef} value={input} placeholder="请输入内容…" onChange={handleInputChange} />
);
antd的Form.useForm
通过const [form] = Form.useForm();
可以获得表单的引用,它提供了诸如validateFields
、resetFields
这样的工具方法。