createRef 和 useRef

两种方式登多可以获取页面元素,其中createRef被用于类组件,useRef被用于函数组件。
如果在函数组件中,错误地使用了createRef,函数组件每次更新渲染的时候,都会重新初始化ref的值:参考

  1. import React, { useRef, createRef, useState } from "react";
  2. import ReactDOM from "react-dom";
  3. import { FormInstance } from 'antd/lib/form';
  4. function App() {
  5. const [renderIndex, setRenderIndex] = useState(1);
  6. const refFromUseRef = useRef<FormInstance>();
  7. const refFromCreateRef = createRef<FormInstance>();
  8. if (!refFromUseRef.current) {
  9. console.log('current.set 1', renderIndex);
  10. refFromUseRef?.current = renderIndex;
  11. }
  12. if (!refFromCreateRef.current) {
  13. console.log('current.set 2', renderIndex);
  14. refFromCreateRef?.current = renderIndex;
  15. }
  16. return (
  17. <div className="App">
  18. Current render index: {renderIndex}
  19. <br />
  20. First render index remembered within refFromUseRef.current:
  21. {refFromUseRef.current}
  22. <br />
  23. First render index unsuccessfully remembered within
  24. refFromCreateRef.current:
  25. {refFromCreateRef.current}
  26. <br />
  27. <button onClick={() => setRenderIndex(prev => prev + 1)}>
  28. Cause re-render
  29. </button>
  30. </div>
  31. );
  32. }
  33. export default App;

在TypeScript中,方法中需要传递具体的泛型,又比如下面这个普通的HTML元素

  1. const textRef = useRef<HTMLTextAreaElement>();
  2. return (
  3. <textarea ref={textRef} value={input} placeholder="请输入内容…" onChange={(e) => { setInput(e.target.value); }} />
  4. );

将onChange的回调,从函数声明 改为 函数名后,必须要给事件对象增加类型。

  1. const textRef = useRef<HTMLTextAreaElement>();
  2. const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
  3. setInput(e.target.value );
  4. }
  5. return (
  6. <textarea ref={textRef} value={input} placeholder="请输入内容…" onChange={handleInputChange} />
  7. );

antd的Form.useForm

通过const [form] = Form.useForm();可以获得表单的引用,它提供了诸如validateFieldsresetFields这样的工具方法。