ReasonReact-Component

Component

Creation

ReasonReact 不需要 class 來建立 Component

提供一個建立的 API 會回傳一個 record

他的欄位是可以覆寫的(就像 render, initialState, didMount… 之類的)

ReasonReact.statelessComponent("TheComponentName")

字串是為了提供 Debuging 他就像是 React 中的 displayName

例如要建立一個新的 Greeting 的 Component

1
2
3
4
5
6
let component = ReasonReact.statelessComponent("Greeting");

let make = (~name, _children) => {
...component,
render: _self => <div>{ReasonReact.string(name)}</div>
};

make 會回傳一個 Component record

Note: 不要直接使用 ReasonReact.statelessComponent直接在 make 中解構,範例如下

1
2
3
4
let make = _children => {
...(ReasonReact.statelessComponent("Greeting")),
render: self => blabla
}

上述範例為錯誤示範,請勿使用

Props

Props 其實就是 make function 中的 labeld arguments

也可以是有選擇性(optional)或有預設值(default value)

例如

1
2
let make = (~name, ~age=?, ~className="box", _children) => 
<div>(ReasonReact.string(name))</div>

最後的一個參數必須是 children 但是如果沒有使用到的話

可以用 _ 或是 _children 來做命名 compiler 會自動規避

props 的名字不能是 ref 或是 key

這部分和 ReactJs 一樣

上面的範例如果只傳入 name

classname 會是預設的 box

age 預設會是 None

有時候在 ReactJs 中會以傳入的值決定回傳的 Component

1
<Foo name="Reason" age={this.props.age} />

如果這樣傳值的話有可能會有 bug

因為 age 有可能是 Null 的

所以可以透過 varian

1
2
3
4
switch (myAge) {
| None => <Foo name="Reason" />
| Some(nonOptionalAge) => <Foo name="Reason" age=nonOptionalAge />
}

這樣看起來有點繁雜

也可以這樣處理

1
<Foo name="Reason" age=?myAge />

這並不是特殊的手法

詳情可以參照 Reason doc

self

你會在 make 中看到 self 他的角色就像是 Javascript 中的 this

它是一個 record 包含了 state, handler, send

也可以傳遞生命週期 API

JSX

Reason 也可以接受 JSX 但是在 bsconfig.json 要給予設定資訊

{"reason": {"react-jsx": 2}

更詳細的 schema

Uncapitalized

1
<div foo={bar}> {child1} {child2} </div>

會編譯為

1
ReactDOMRe.createElement("div", ~props=ReactDOMRe.props(~foo=bar, ()), [|child1, child2|]);

Javascript 會編譯為

1
React.createElement('div', {foo: bar}, child1, child2)

prop-less 範例

1
<div />

則會轉譯成

1
ReactDOMRe.createElement("div", [||]);

實際的 Javascript

1
React.createElement('div', undefined);

Note: ReactDOMRe.createElement 是內部轉譯 JSX 專用,也有提供逃生出口 ReasonReact.createDomElement 詳情閱讀 children section

Capitalized

1
<MyReasonComponent key={a} ref={b} foo={bar} baz={qux}> {child1} {child2} </MyReasonComponent>

會轉譯為

1
2
3
4
5
ReasonReact.element(
~key=a,
~ref=b,
MyReasonComponent.make(~foo=bar, ~baz=qux, [|child1, child2|])
);

prop-less <MyReasonComponent /> 則會轉譯成

1
ReasonReact.element(MyReasonComponent.make([||]));

MyReasonComponent.make 中的 make 跟上一個部分講的 make 是一樣的

也要注意不要將 ref key 這類的保留自使用在 props

Fragment

在 ReasonReact 中也允許使用 Fragment

他可以簡化 DOM 結構

1
<> child1 child2 </>;

將會轉意成為

1
ReactDOMRe.createElement(ReasonReact.fragment, [|child1, child2|]);

Javascript 則會

1
React.createElement(React.Fragment, undefined, null);

Children

ReasonReact 中的 children 是有完整的類型

你可以傳遞任何型態的值給它

1
2
3
4
<MyReasonComponent> <div /> <div /> </MyReasonComponent>

let let theChildren = [| <div />, <div /> |];
<MyReasonComponent> theChildren </MyReasonComponent>

上面兩個範例都會轉譯為

1
2
3
4
let theChildren = [| <div />, <div /> |];
ReasonReact.element(
MyReasonComponent.make([|theChildren|])
);

Reason 中的 children 也可以使用 spread

1
2
let theChildren = [| <div />, <div /> |];
<MyReasonComponent> ...theChildren </MyReasonComponent>

詳情可以參閱 children spread syntax

更詳細的 Children 後續會再做了解

文章目录
  1. 1. Component
    1. 1.1. Creation
  2. 2. Props
    1. 2.1. self
  3. 3. JSX
    1. 3.1. Uncapitalized
    2. 3.2. Capitalized
    3. 3.3. Fragment
    4. 3.4. Children
|