I might make a video on React component in ReScript

Hello,

As a bit of an exercise I’d like to make a YouTube video on how React components in ReScript work.
I’m not sure if I’m actually going to do it, but content creation does interest me from time to time.

Anyway, this is what I have in mind to cover. Would be great to hear some thoughts on this list.
Did I miss anything?

Getting Started with ReScript

  • Run the command: bun create rescript-app@next
  • Use v12 alpha
  • Inspect the rescript.json file:
    • Set jsx to version 4
    • Include @rescript/react
  • Start the ReScript watcher with: bunx rescript -w
  • Run the development server with: bun run dev

Define a React Component

  • You need a function called make that takes a props record as a single property.
  • The make function allows JSX syntax to work for that module.
  • <Foo /> is shorthand for invoking the Foo.make function.
  • You can spread ...ReactDOM.domProps to allow optional existing well-known properties.
  • You can create an instance of that element in another module (use <Foo /> in App.res).
  • Every file in ReScript is a module, which means you cannot reuse a file name.
  • Each module can have only one make function, but you can have nested modules.
  • The name of the component is determined by the module name.
  • Each React component must return the React.element type.
  • You can compose other elements and primitive types.
  • You cannot use raw text in JSX as the type wouldn’t match.
  • Convert primitives like strings using ->React.string.

@react.component Attribute

  • You can use labeled arguments to define your props; in this case, annotate your function with @react.component.
  • Use unit when you have no props.
  • @react.component transforms your source code and creates a prop type behind the scenes.
  • Due to this transformation, you must use unit or all labeled arguments; otherwise, the compiler will complain.
  • It also transforms the make function to an uppercased function with the module name.

@react.componentWithProps Attribute

  • Use this when you want to define a record type yourself but still want the transformation of make to uppercase module name function.
  • It is recommended to always use this attribute for better compatibility with the wider React ecosystem.

Fast Refresh

  • Inspect the change in the react() plugin in vite.config.js.
  • Everything is public in ReScript by default.
  • For fast refresh to work in Vite, only components can be exported.
  • We use signature files to achieve this.

ESLint & React Compiler

  • Writing ReScript code does not guarantee adherence to React’s rules.
  • Linting the output JavaScript code can be helpful.
  • Set up for linting and the React compiler should be shown.
  • Add @directive("'use memo'") to make it work.
4 Likes

This looks like a good plan!

1 Like

I have only dabbled with ReScript so far and one of my first attempts was trying to extend the props of a react component. Firstly, by the approach that you plan to cover, i.e. spreading the existing props and adding custom props to a component. Secondly, by extending JsxDOM.domProps itself, e.g. to add popover and popovertarget. If not too out of scope, covering the latter might be a nice addition.

Looking forward to seeing the video :slight_smile:

2 Likes

Could you provide an example of how to extend JsxDOM.domProps? I’m not sure I understand.

It is basically what @tsnobip outlined here

1 Like

I see, so when you don’t control the component (like the <button> in the standard library), you can extend it. Thanks for bringing this up!

1 Like

We could make this configurable for the React PPX as well. I think this has been requested before. We could add a setting to the JSX config, like "domProps": "MyDOMProps.t". Then it’d be easy to just do a type t = {...JsxDOM.domProps, someOtherProp?: bool} without having to set up a full custom JSX transform.

5 Likes

This would be really great. I want to use the popover attribute quite often but am too lazy to overwrite the whole jsx stuff.

My workaround is by using a ref and setAttribute in a useEffect hook.

But in the popover case, maybe we could extend the props in the core, since it is baseline?!

1 Like

It would make sense to create a PR to add popover and popoverTarget to the dom props indeed in this case!

3 Likes

Yes definitely, that’s the real solution to that particular problem. The config would be:

  • An escape hatch so you’re never blocked
  • When you need to add non-standard things like binding to data- attributes, and so on
2 Likes

With some cheating you can also do this:

Depending on how much you need this, this might be easier instead of overriding domProps.

1 Like