DEV Community


Posted on

Form in a Semantic UI React Modal

Modality is a design technique that draws a person's attention to a task or some important information. A modal grabs a user's attention by covering and temporarily disabling interactions with the main view of the site until the user dismisses the modal by clicking the close button or clicking anywhere outside of the modal.

I like to put short forms in modals because doing so allows the website to stay clean and simple. In this post, I'll be going over how I implement a controlled form in a controlled modal using React and the Modal component from Semantic UI React.

Install semantic-ui-react library

Run the following in your React project

npm i semantic-ui-react  OR  yarn add semantic-ui-react

Create a form component

In React, you want to create a controlled form. A controlled form is a form that derives its input values from state and updates state. Controlled forms are useful because we can easily pass the form data to other components.

You can use the Form component that Semantic UI React offers or just the regular HTML form tag. If you plan to use the

component, remember to import it
import { Form } from "semantic-ui-react";
// src/components/Login.js

import React, { Component } from "react";

class Login extends Component {
  state = {
    fields: {
      username: "",
      password: "",

  handleChange = (e) => {
    const newFields = { ...this.state.fields, []: };
    this.setState({ fields: newFields });

  handleLoginSubmit = (e) => {
    // whatever you want to do when user submits a form

  render() {
    const { fields } = this.state;

    return (
          <form onSubmit={(e) => {
            <label htmlFor="username">Username</label>
            <label htmlFor="username">Password</label>
            <button>Log In</button>

export default Login;

Notice that I am calling a method handleClose() when the form is submitted. I will explain in the Create modal section why I am invoking this method.


At the top of the file of the component where you want to use the Modal, add

import { Modal } from "semantic-ui-react";

Create modal

In a separate file from Login.js, I'll just call it Modal.js. Remember to import the form into this file.

// src/components/Modal.js

import Login from "./Login";

class PostsList extends Component {
  state = {
    modalOpen: false,

  handleOpen = () => this.setState({ modalOpen: true });

  handleClose = () => this.setState({ modalOpen: false });

  render() {
    return (
          <button onClick={this.handleOpen}>Login</button>
              <Login handleClose={this.handleClose} />

To create a controlled modal, we will need state. Notice in the state I have a key, modalOpen, that I initially set to false. I will be using that property to handle opening or closing the modal.

I also wrote methods, handleOpen and handleClose, which will set modalOpen in state to true or false. I will explain these in a bit.

The Modal component has many props, such as open. This prop takes a boolean value and controls whether or not the Modal is displayed. If open=true, then the Modal is displayed. Set open={this.state.modalOpen}. Because modalOpen is initially set to false, the Modal is not displayed.

To open the Modal, we have a button that says Login. When a user clicks the button, handleOpen method will be called, changing modalOpen from false to true, which will display the Modal.

The Modal component also has onClose prop that will invoke handleClose when the modal is closed, setting modalOpen back to false.

Notice I am passing the handleClose method to the Login component. This is because I want the modal to close when the user submits the form. Without this method, the user would have to submit the form and then click the close icon or click outside of the modal in order to close the modal.

A Modal has three main sections, the header, content, and footer, but you don't have to include all three. The Login component (the form) will go in between Modal.Content, which is the body of the Modal.

When you are done, you should have something that looks like this:
Alt Text

Top comments (0)