Form in a Semantic UI React Modal
Tags: react, javascript
Published: 2020-06-16 05:41:30

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](https://www.npmjs.com/package/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 <Form> component, remember to import it
```
import { Form } from "semantic-ui-react";
```

```javascript
// src/components/Login.js

import React, { Component } from "react";

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

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

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

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

    return (
          <form onSubmit={(e) => {
            this.handleLoginSubmit(e);
            this.props.handleClose();
           }}>
            <label htmlFor="username">Username</label>
            <input
              className="username"
              type="text"
              name="username"
              placeholder="Username"
              value={fields.username}
              onChange={this.handleChange}
            ></input>
            <label htmlFor="username">Password</label>
            <input
              className="password"
              type="password"
              name="password"
              placeholder="Password"
              value={fields.password}
              onChange={this.handleChange}
            ></input>
            <button>Log In</button>
          </form>
    );
  }
}

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.

## Import
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.

```javascript
// 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 (
       <div>
          <button onClick={this.handleOpen}>Login</button>
          <Modal
            open={this.state.modalOpen}
            onClose={this.handleClose}
            closeIcon
          >
            <Modal.Header>Login</Modal.Header>
            <Modal.Content>
              <Login handleClose={this.handleClose} />
            </Modal.Content>
          </Modal>
        </div>
     )
   }
}

```
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](https://dev-to-uploads.s3.amazonaws.com/i/njtroi84cq9ogx3pnrif.png)