Home > OS >  React - child.ref.current is null in componentdidmount
React - child.ref.current is null in componentdidmount

Time:02-02

Here's many similar questions but I still couldn't solve this problem.

Child's ref is null in Listner.

I really don't understand what this is.

The code is below.

  • react 17.0.1
// 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,
  );
});

Any advice for me? Thanks.

CodePudding user response:

You need to use useRef for creating the ref in React Function Components, so change it to this:

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>
  );
};
  •  Tags:  
  • Related