Skip to content

How to properly use Modal in Fluent UI

I am new to React and Fluent UI, I loaded all my files from CDNs, when I tried execute the following code, the modal didn’t open. Please tell me what I am doing wrong here. I searched up examples but wasn’t able to find one. Here is the code:

  const { DefaultButton,Fabric,Modal,IconButton} = window.FluentUIReact;
    const app = () =>{
      var isModalOpen = false;
      function showModal(){
        isModalOpen = true;
      }
      function hideModal(){
        isModalOpen = false;
      }
      return (
        <Fabric applyThemeToBody>
        <DefaultButton onClick={showModal}>Make a Poll</DefaultButton>
        <Modal
            titleAriaId={"id"}
            isOpen={isModalOpen}
            onDismiss={hideModal}
            isBlocking={true}
          >
            <div>
              <span id={"id"}>Lorem Ipsum</span>
              <IconButton
                iconProps = {{iconName: 'Cancel'}}
                ariaLabel="Close popup modal"
                onClick={hideModal}
              />
            </div>
            <div>
              <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lorem nulla, malesuada ut sagittis sit
                amet, vulputate in leo. Maecenas vulputate congue sapien eu tincidunt. Etiam eu sem turpis. Fusce tempor
              </p>
            </div>
          </Modal>
        </Fabric>
      );
    };

    ReactDOM.render(app(), document.getElementById('app'))
<div id="app"></div>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@fluentui/[email protected]/dist/fluentui-react.js"></script>
  <script src="https://unpkg.com/@uifabric/[email protected]/dist/react-hooks.js"></script>
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
  <script defer type="text/babel" src="script.jsx"></script>

Thanks in advance

Answer

If you use isModalOpen = true/false React will never know that it is supposed to re-render the view. React offers the useState hook to store state. You can then call the setter to update the value and notify React that it has to re-render the component.

You may only call hooks inside components and custom hooks. So we have to convert the function app into a component. This is simply done by changing the name of the function to start with a capital letter.

From Components and Props:

Note: Always start component names with a capital letter.

React treats components starting with lowercase letters as DOM tags. For example, <div /> represents an HTML div tag, but <Welcome /> represents a component and requires Welcome to be in scope.

To learn more about the reasoning behind this convention, please read JSX In Depth.

After making this change we also need to update the way we call App. Instead of passing app() to ReactDOM.render() we now pass <App />.

const { useState } = React;
const { DefaultButton, Fabric, Modal, IconButton } = FluentUIReact;

const App = () =>{
  const [isModalOpen, setIsModalOpen] = useState(false);
    
  function showModal() {
    setIsModalOpen(true);
  }
  function hideModal() {
    setIsModalOpen(false);
  }
  return (
    <Fabric applyThemeToBody>
      <DefaultButton onClick={showModal}>Make a Poll</DefaultButton>
      <Modal
        titleAriaId="id"
        isOpen={isModalOpen}
        onDismiss={hideModal}
        isBlocking={true}
      >
        <div>
          <span id="id">Lorem Ipsum</span>
          <IconButton
            iconProps = {{iconName: 'Cancel'}}
            ariaLabel="Close popup modal"
            onClick={hideModal}
          />
        </div>
        <div>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lorem nulla, malesuada ut sagittis sit
            amet, vulputate in leo. Maecenas vulputate congue sapien eu tincidunt. Etiam eu sem turpis. Fusce tempor
          </p>
        </div>
      </Modal>
    </Fabric>
  );
};

ReactDOM.render(<App />, document.getElementById('app'))
<div id="app"></div>

<script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@fluentui/[email protected]/dist/fluentui-react.js"></script>
<script src="https://unpkg.com/@uifabric/[email protected]/dist/react-hooks.js"></script>