ReasonReact-LifeCycle

LifeCycle

ReasonReact 也有類似 ReactJS 的生命週期

  • didMount: self => unit

  • willReceiveProps: self => state

  • shouldUpdate: oldAndNewSelf => bool

  • willUpdate: oldAndNewSelf => unit

  • didUpdate: oldAndNewSelf => unit

  • willUnmount: self => unit

Note

  • 移除了所有 component 前綴
  • willReceiveProps 需要回傳的是 state 預設是假設你每次都要修改狀態,不然也可以直接回傳 state
  • didUpdate, willUnmountwillUpdate 不可以修改 state
  • 不支援 willMount 請用 didMount
  • didUpdate, willUpdateshouldUpdate 的 input 是 oldAndNewSelf record, 類型是 {oldSelf: self, newSelf: self}

如果你真的在 lifecycle 中修改 state, 請發一個 Action self.send(DidMountUpdate)

retainedProps

ReactJS 中有時會使用到 prevProps(componentDidUpdate) 或是 nextProps(componentWillUpdate) 這類的 API

但是 ReasonReact 中沒有這個部分, 則是要使用 retainedProps 來實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
type item = {
title: string,
completed: bool
};

type retainedProps = {message: string};

module TodoItem = {
let component = ReasonReact.statelessComponentWithRetainedProps("TodoItem");
let make = (~item, ~message, _children) => {
...component,
retainedProps: {message: message},
didUpdate: ({oldSelf, newSelf}) => {
if (oldSelf.retainedProps.message !== newSelf.retainedProps.message) {
Js.log("props `message` changed!")
}
},
render: (_self) =>
<div className="item">
<input
checked=(item.completed)
/* TODO make interactive */
/>
(ReasonReact.string(item.title))
</div>
};
};

type state = {items: list(item)};

type action =
| AddItem;

let component = ReasonReact.reducerComponent("TodoApp");

let newItem = () => {title: "Click a button", completed: true};

let make = (_children) => {
...component,
initialState: () => {
items: [
{title: "Write some things to do", completed: false}
]
},
reducer: (action, {items}) =>
switch action {
| AddItem => ReasonReact.Update({items: [newItem(), ...items]})
},
render: (self) => {
let numItems = List.length(self.state.items);
<div className="app">
<div className="title">
(ReasonReact.string("What to do"))
<button onClick=(_event => self.send(AddItem))>
(ReasonReact.string("Add something"))
</button>
</div>
<div className="items">
(
self.state.items
|> List.map((item) => <TodoItem item />)
|> Array.of_list
|> ReasonReact.array
)
</div>
<div className="items"> (ReasonReact.string("Nothing")) </div>
<div className="footer">
(ReasonReact.string(string_of_int(numItems) ++ " items"))
</div>
</div>
}
};

ReasonReact 提供了 ReasonReact.statelessComponentWithRetainedPropsReasonReact.reducerComponentWithRetainedProps

這兩個方法只是讓你的 make 函數中可以多一個 retainedProps

willReceiveProps

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
type item = {
title: string,
completed: bool
};

type retainedProps = {message: string};

module TodoItem = {
let component = ReasonReact.statelessComponentWithRetainedProps("TodoItem");
let make = (~item, ~message, _children) => {
...component,
retainedProps: {message: message},
willReceiveProps: (self) => {
if (self.retainedProps.message === message) {
Js.log("willReceiveProps");
};
},
didUpdate: ({oldSelf, newSelf}) => {
if (oldSelf.retainedProps.message !== newSelf.retainedProps.message) {
Js.log("props `message` changed!")
}
},
render: (_self) =>
<div className="item">
<input
checked=(item.completed)
/* TODO make interactive */
/>
(ReasonReact.string(item.title))
</div>
};
};

type state = {items: list(item)};

type action =
| AddItem;

let component = ReasonReact.reducerComponent("TodoApp");

let newItem = () => {title: "Click a button", completed: true};

let make = (_children) => {
...component,
initialState: () => {
items: [
{title: "Write some things to do", completed: false}
]
},
reducer: (action, {items}) =>
switch action {
| AddItem => ReasonReact.Update({items: [newItem(), ...items]})
},
render: (self) => {
let numItems = List.length(self.state.items);
<div className="app">
<div className="title">
(ReasonReact.string("What to do"))
<button onClick=(_event => self.send(AddItem))>
(ReasonReact.string("Add something"))
</button>
</div>
<div className="items">
(
self.state.items
|> List.map((item) => <TodoItem item />)
|> Array.of_list
|> ReasonReact.array
)
</div>
<div className="items"> (ReasonReact.string("Nothing")) </div>
<div className="footer">
(ReasonReact.string(string_of_int(numItems) ++ " items"))
</div>
</div>
}
};

ReactJS 的 componentWillUpdate 中的參數 nextPropsmake 的參數

而現在的 props (this.props) 是上面的 retainedProps,可以透過 {oldSelf} 得到

didUpdate

ReactJS 的 prevProps 可以透過 retainedProps 拿到,需要使用 oldSelf

shouldUpdate

和 ReactJS 的 shouldComponentUpdate 對應

文章目录
  1. 1. LifeCycle
    1. 1.1. retainedProps
    2. 1.2. willReceiveProps
    3. 1.3. didUpdate
    4. 1.4. shouldUpdate
|