1

Trying to invoke modal function from outside, but not possible. Achieved with class component using static method and properties, but this will not work there. Observers are giving some issues, finally landing to stateless component. How best way we can make this work?

//Inside
import Modal from './modal';
   // Not working
   <Button onClick={Modal.showModal}
<Modal />


//Outside

export const Modal = () => {
  const [visible, setVisible] = useState(false);

  const showModal = () => {
     setVisible(true);
  }
  return(
     <Dialog visible={visible}>Hello Test</h1>
  )
}
Mithun Shreevatsa
  • 3,588
  • 9
  • 50
  • 95

3 Answers3

0

You can declare setVisible in parent component:

  const [visible, setVisible] = useState(true);

Then pass the set function to Modal:

 <Modal visible={visible} setVisible={setVisible} />

Set visible from outside:

  <button onClick={() => setVisible(!visible)}>Click</button>

Sample: https://codesandbox.io/s/competent-bassi-x3dqd?file=/src/App.js:267-325

Viet
  • 12,133
  • 2
  • 15
  • 21
  • Thanks for your response, but is there a better solution than this rather than props? Because the component is mounted already and the state should be changed invoking a function inside – Mithun Shreevatsa Feb 10 '21 at 07:53
0

You will need to "lift the state up" to a component that will pass the state and the state handlers to his children, or use some global state with redux or context.

Example:

<App>:

import Modal from "./modal";
import { useState } from "react";

const [visible, setVisible] = useState(false);

const showModal = () => {
  setVisible(true);
};

return (
  <> 
    <Button onClick={showModal}> Hide Modal </Button>
    <Modal visible={visible} />
  </>
);

<Modal>:

export default const Modal = ({ visible }) => {
  return (
    <Dialog visible={visible}>
      <h1>Hello Test</h1>
    </Dialog>
  );
};

Also, by only using the export keyword, you can import only single export from a module, therefore you can't use the default import syntax import Modal from "..." and you will be required to import as such - import { Modal } from '...'

Dyn4sty
  • 166
  • 4
0

I managed to solve usingEffect here, but not sure if this is perfect for my implementation. I am trying to update the state for already mounted component.

useEffect(() => {
    if (props.visible) {
      showModal();
    }
  }, [props.visible]);

And handled resetState with a callback prop

Mithun Shreevatsa
  • 3,588
  • 9
  • 50
  • 95