React hooks 父组件 调用 子组件 方法 使用useRef() TS2322错误

父组件

const pchildref:any  = useRef();

const setImmediate = (num: number) => {
    changeScope({...Object.assign(obj, {init:num})})
}

function handlerClick(){
    console.log(pchildref.current._childFn())
}

return (
    <>
        <div className="title" onClick={handlerClick}>{obj.start}到{obj.end}</div>
        <Boxs ref={pchildref} init={init}></Boxs>
    </>
)

子组件

import React, { useImperativeHandle, useRef, forwardRef } from "react"

const Boxs = (props: { init: React.ReactNode; }, ref:any) => {

const childRef = useRef()
useImperativeHandle(ref, () => {
    return {
        _childFn() {
            return "父组件 调用 子组件"
            // something….
        }
    }
})

return (
    <div ref={childRef} className="box">{props.init}</div>
)

}

export default forwardRef(Boxs)

报错信息:

  ref={childRef}
 Type 'undefined' is not assignable to type 'HTMLDivElement | null' TS2322  
 在线等
阅读 9.9k
2 个回答

ref属性是react内置属性,不会作为props传给子元素。你可以换个名字wrapRef:

const pchildref:any  = useRef();

const setImmediate = (num: number) => {
    changeScope({...Object.assign(obj, {init:num})})
}

function handlerClick(){
    console.log(pchildref.current._childFn())
}

return (
    <>
        <div className="title" onClick={handlerClick}>{obj.start}到{obj.end}</div>
        <Boxs wrapRef={pchildref} init={init}></Boxs>
    </>
)
import React, { useImperativeHandle, useRef, forwardRef } from "react"

const Boxs = (props: { init: React.ReactNode; }, wrapRef:any) => {
const childRef = useRef()
useImperativeHandle(wrapRef, () => {
    return {
        _childFn() {
            return "父组件 调用 子组件"
            // something….
        }
    }
})

return (
    <div ref={childRef} className="box">{props.init}</div>
)

写成 const pchildref = useRef<any>();
pchildref.current 的类型是什么 TS 并不知道,因为你没有通过 useRef<类型> 或者 useRef(对象结构) 传入
上面是简单方法,如果你想写的类型足够完善可以改成这样

type Ref = {
  _childFn(): string;
};

const Boxs: React.ForwardRefRenderFunction<Ref, any> = (
  props: { init: React.ReactNode },
  ref: any
) => {
  const childRef = useRef();
  useImperativeHandle(ref, () => {
    return {
      _childFn() {
        return '父组件 调用 子组件';
        // something….
      }
    };
  });

  return (
    <div ref={childRef} className="box">
      {props.init}
    </div>
  );
};

const VO = forwardRef(Boxs);

const Oarebt = () => {
  const pchildref = useRef<Ref>();

  function handlerClick() {
    console.log(pchildref.current._childFn());
  }

  return (
    <>
      <div className="title" onClick={handlerClick}>
        <VO ref={pchildref} init={<Text></Text>} />
      </div>
    </>
  );
};
推荐问题