Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 2592

Even more JSX customization

$
0
0

About the single parameter of JSX components, I’m not sure to follow, do you have examples of such components that don’t follow this rule? How are they used?

The type of a component (in rescript) is always something like this: props => Jsx.element

In mithril for example the type would look like this: vnode => mithrilComponent
Where the so called props (e.g. in react) are just a sub property (attrs) of vnode.

<Counter initialValue=10 /> ← the compiler has to know, that the initialValue comes from “vnode.attrs” not from “props”.

// js
const Counter = vnode => {
    let count = vnode.attrs.initialValue;

    return {
        view: _ => (
            <div>
                <button onclick={_ => { count++ }}>click me</button>
                {count}
            </div>
        ),
    };
}

The rescript implementation will fail.

// res
let make = vnode => {
    let count = ref(vnode.attrs.initialValue)

    {
        view: _ => {
            <div>
                <button onClick={_ => count.contents = count.contents + 1}>
                    {Jsx.string("click me")}
                </button>
                {Jsx.int(count.contents)}
            </div>
        },
    }
}

While I can cast it with my component / componentP functions (s. previous post), the type system wouldn’t complain about react like implementations and if the attrs type is generic, it will throw this error “This expression’s type contains type variables that cannot be generalized: ‘_weak1 => Jsx.element’”.

Example:

type props<'a> = {
  options: array<'a>,
  getOptionId: 'a => string,
  getOptionLabel: 'a => string,
}

let make = M.componentP(_ => {
  view: vnode => {
    <ul>
    </ul>
  },
})

Additionally the “hyperscript” function type (for native elements) looks like this in mithril:

@module("mithril") external m: (string, domProps, option<element>) => element = "m"

So I have to normalize the props before:

let createElement = (tag: string, props: domProps) => {
  let (props, children) = normalize(props)

  m(tag, props, children)
}

Would be nice if you could specify, how the jsx code will be transformed.


Viewing all articles
Browse latest Browse all 2592

Trending Articles