如果组件是使用 React.Fragment 有多个元素,要指明实际是哪元素的 ref

    1. const Foo = forwardRef((props, ref) => {
    2. return (
    3. <>
    4. <h1 ref={ref}></h1>
    5. <input type="input" />
    6. </>
    7. )
    8. })

    如果多个元素都的一部分信息都要在 ref 中,那么可以使用 useImperativeHandle 来封装 ref 再用 forwardRef 传回去

    1. const Foo = forwardRef((props, ref) => {
    2. const h1Ref = useRef();
    3. const inputRef = useRef();
    4. useImperativeHanlde(ref, ()=> {
    5. h1: h1Ref.current,
    6. focus: inputRef.current.focus
    7. }, []);
    8. return (
    9. <>
    10. <h1 ref={h1Ref}></h1>
    11. <input type="input" ref={inputRef}/>
    12. </>
    13. )
    14. })

    函数组件不能给 ref,会报错
    image.png

    1. const Foo = props => {
    2. const inputRef = useRef();
    3. onClick = () => {
    4. inputRef.current.focus();
    5. }
    6. return (
    7. <div>
    8. <input type="text" ref={inputRef} />
    9. <button onClick={onClick}>聚集</button>
    10. </div>
    11. )
    12. }
    13. const App = props => {
    14. const FooRef = createRef();
    15. const onClick = () => {
    16. FooRef.current.onClick();
    17. }
    18. // Foo 是函数组件指定 ref 会报错
    19. return (
    20. <div>
    21. <Foo ref={FooRef}/>
    22. <button onClick={onClick}>父组件</button>
    23. </div>
    24. )
    25. }

    这时会可用 forwardRef 来转发 Ref,使用 forwardRef 对函数组件进行包裹

    1. const Foo = forwardRef(
    2. (props, inputRef) => {
    3. onClick = () => {
    4. inputRef.current.focus();
    5. }
    6. return (
    7. <div>
    8. <input type="text" ref={inputRef} />
    9. <button onClick={onClick}>聚集</button>
    10. </div>
    11. )
    12. }
    13. )
    14. const App = props => {
    15. const FooRef = createRef();
    16. const onClick = () => {
    17. FooRef.current.focus(); // 这里直接拿到子组件的 DOM
    18. }
    19. return (
    20. <div>
    21. <Foo ref={FooRef}/>
    22. <button onClick={onClick}>父组件</button>
    23. </div>
    24. )
    25. }