loading...

Learning ReasonReact Step by Step Part: 2

Sophia Brandt on September 15, 2019

By now we have the HTML/JSX skeleton for our input form: a simple login form styled with Bulma. (The code is available on Github.) Stumbli... [Read Full]
markdown guide
 

I'm enjoying your "Learning ReasonReact" series so far. I good luck with your Reason project!

Here's a few things that may help:

A React hook is just a function, not a React component. Instead of this:

module UseForm = {
  [@react.component]
  let make = (~callback) => {
      ...
    }
  }
};

You should just use this:

let useForm = (~callBack) => {
  ...
}

Inside your handleChange function, targetName and targetValue are both functions, not strings, which is probably where your compiler error is coming from.

Try this instead:

let targetName = evt->ReactEvent.Form.target##name;

(Similarly, {j|$targetName|j} compiles to JS String(targetName), so it's just the JS string representation of the function.)

If you're coming from a JavaScript background and Reason is giving you trouble, it's always good to look at the *.bs.js files and see how they're actually being compiled. Often, that will help explain what's really going on in the Reason code.

To answer your other questions:

the Js.Dict type in Reason is useful for interoperability with JavaScript, but Reason doesn't provide a lot of tools for working with it (like merging dicts). If you're writing pure Reason code, then you may want to look into the BuckleScript data types. Unfortunately, their documentation isn't very newbie-friendly, but they're great to use once you get the hang of them. To replace a dict, you'll want a Belt.Map.String or Belt.HashMap.String. They work almost exactly the same way that the standard OCaml data containers work: ocaml.org/learn/tutorials/comparis...

With forms, most of the time you can control exactly what the fields are, so a record is probably more appropriate than a dict or a map. ReasonReact (and ReactJS) discourage using useState with complex data types (dicts, records, maps, etc.). useReducer is a much better option. It works in ReasonReact almost exactly the same way it does in ReactJS.

As for file (module) structure, you can put as many hooks (or components!) as you want inside each file. Hooks are just functions. Components are modules, and you can nest modules inside modules.

I hope that info helps point you in the right direction. For anyone reading this who's having trouble using ReasonReact for the first time, don't hesitate to check out the community! The Reason forums and Discord are active and friendly to newbies.

 

Thank you, that's super helpful.
I'm very grateful for your feedback. It will tremendously help in continuing the project!

 

Hi Sophia, you are on the right track. I agree with John that Belt.Map.String seems like the right data structure here. It's an immutable data structure that offers get/set/update/merge operations, pretty much exactly what you need.

Regarding file structure, I wrote something about that, which you may find helpful: dev.to/yawaramin/a-modular-ocaml-p...

code of conduct - report abuse