kyun
kyun

Reputation: 10264

How to pass prop to component's children

const ListView = () => {
  return(
    <ul>
      <ListItem modal={<Modal />} />
    </ul>
  )
};

const ListItem = (props) => {
  const [visible, setVisible] = useState(false);
  const toggle = () => setVisible(!visible)

  return (
    <>
      <li>
        ListItem 
      </li>
      <ModalWrapper toggle={toggle}>{props.modal}</ModalWrapper>
    </>
  )
}

const ModalWrapper = (props) => {
  if(!props.visible) return null;
  return (
    <>
      {props.children}
    </>
  )
}

const Modal = ({ toggle }) => {
  /* I would like to use toggle() here. */
  return (
    <>
      <div onClick={toggle} className="dimmer"></div> 
      <div className="modal">modal</div>
    </>
  )
}

I have a function toggle() in <ListItem /> as shown above.

I am struggling to use toggle() in <Modal />.

Is it possible or are there any suggestions?

Upvotes: 1

Views: 57

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53874

You need to inject toggle to ModalWrapper children, be careful not to override toggle prop on Modal after it.

const ModalWrapper = ({ children, visible, toggle }) => {
  const injected = React.Children.map(children, child =>
    React.cloneElement(child, { toggle })
  );
  return <>{visible && injected}</>;
};

Refer to React.cloneElement and React.Children.map.

Demo:

Edit SO-Q-56529259

Upvotes: 1

Related Questions