Let's continue from yesterday's post and build the skeleton for our application: a simple form with ReasonReact and hooks.

Go to the src folder.

The main App.re file should just render a Form component:

[@react.component]
let make = () => <Form />;

The syntax looks unfamiliar. What is [@react.component]?

It is a decorator attribute and tells ReasonReact that you're writing a React component. Duh!

The latest ReasonReact version uses React hooks under the hood.

Your app will throw an error because we don't have a Form component yet (src/Form.re):

// create an alias for ReasonReact. String,
// so that we don't have to type out the full function every time
let str = ReasonReact.string;

[@react.component]
let make = () =>
  <div className="section is-fullheight">
    <div className="container">
      <div className="column is-4 is-offset-4">
        <div className="box">
          <form>
            <div className="field">
              <label className="label"> {"Email Address" |> str} </label>
              <div className="control">
                <input
                  className="input"
                  type_="email"
                  name="email"
                  required=true
                />
              </div>
            </div>
            <div className="field">
              <label className="label"> {"Password" |> str} </label>
              <div className="control">
                <input
                  className="input"
                  type_="password"
                  name="password"
                  required=true
                />
              </div>
            </div>
            <button
              type_="submit" className="button is-block is-info is-fullwidth">
              {"Login" |> str}
            </button>
          </form>
        </div>
      </div>
    </div>
  </div>;

As you can see, in Reason (and Ocaml) the filename serves as the namespace for the module/component.

Here we set up a HTML form with Bulma classes for styling. Like in React, we have to replace class with className.
type is a reserved keyword, so you have to use type_.
You also have to spell out that the input field is required by writing required=true. With React, you could omit the =true assignment. In ReasonReact, you have to be explicit.

Further Reading