React - child.ref.current 在 componentdidmount 中为空

React - child.ref.current is null in componentdidmount

这里有很多类似的问题,但我还是没能解决这个问题。

Child's ref 在 Listner 中为空。

我真的不明白这是什么

代码如下。

// Parent.tsx
const Parent: React.FC<{id: string}> = (props) => {
  const [id] = useState(props.id)  
  const modalRef = createRef<ModalRef>();

  // If I registerd the Listner here, modalRef is not null but,
  // multiple Listner has registered.

  useEffect(() => {
    listner.on('MODAL_POPUP', (o:{param:string}) => {
      modalRef.current?.pop(o.param); // <--- modalRef.current is null
    });
    return() => {};
  }, []);

  return (
    <Modal ref={modalRef} id={id}>
      <div>contents</div>
    </Modal>
  );
};
// Modal.tsx
export interface ModalProps {
  id: string;
}
export interface ModalRef {
  pop: () => void;
}

const Modal = React.forwardRef<ModalRef, ModalProps>((props, ref) => {
  const [id] = useState(props.id);

  useImperativeHandle(ref, () => ({
    pop() {
      console.log('popup modal');
    },
  }));

  return createPotal(
    <div>contents..</div>,
    document.getElementById('modal-root') as HTMLElement,
  );
});

对我有什么建议吗? 谢谢

你需要使用 useRef 在 React 函数组件中创建 ref,所以将其更改为:

const Parent: React.FC<{id: string}> = (props) => {
  const [id] = useState(props.id)  
  const modalRef = useRef<ModalRef>(); // <== here

  useEffect(() => {
    listner.on('MODAL_POPUP', (o:{param:string}) => {
      modalRef.current?.pop(o.param); 
    });
    return() => {
      listner.off('MODAL_POPUP', ()=>{});
    };
  }, []);

  return (
    <Modal ref={modalRef} id={id}>
      <div>contents</div>
    </Modal>
  );
};