React 16.3
Context API
見 [React 16_3 | Context](/React 16.3_Context.md)
createRef API
React.createRef() 用以簡化 ref 綁定
-
實際的 DOM/ReactComponent 為
aRef.current -
仍支援 callback ref (function 寫法) 綁定。
-
適用於綠葉角色的元件設計,例如:EUButton(、EUInput)。
class ExampleInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
/** @override */
componentDidMount() {
const DOM = this.inputRef.current
}
/** @override */
render() {
return <input ref={this.inputRef}/>
}
}
forwardRef API
把 ReactComponent 內的 ref 提供給父元件,做為自身的 Ref。
- 配合 HOCs 設計使用。
const EUButtonBase = React.forwardRef((props, ref) => (
<props.type
className={this.props.className}
ref={ref}
>
{props.children}
</props.type>
))
class EUButton extends React.Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
render() {
return (
<EUButtonBase
className="eu-button"
ref={this.ref}
>
<i className={`eu-icon ${this.props.icon}`}/>
<span className="eu-button_content">{this.props.name}</span>
</EUButtonBase>
);
}
}
Lifecycle API
graph TB
0(Init)-->A(static getDerivedStateFromProps)
A-->B(componentDidMount)
A-->C(shouldComponentUpdate)
C-->D(getSnapshotBeforeUpdate)
D-->E(componentDidUpdate)
既有 API 修改
16.3 版本還是可以使用原本的 API
componentWillMount→UNSAFE_componentWillMountcomponentWillReceiveProps→UNSAFE_componentWillReceivePropscomponentWillUpdate→UNSAFE_componentWillUpdate
getDerivedStateFromProps API
static getDerivedStateFromProps(props, state):nextState- 為 static,需回傳作為下個 state 的 Object
- 元件沒有 state 時,在 dev 版的 library 在 console 會提示。
class Example extends React.Component {
static getDerivedStateFromProps(props, state) {
// ...
}
}
getSnapshotBeforeUpdate API
-
在
componentDidUpdate前執行 -
回傳值作為 componentDidUpdate 第三個參數使用;如無需要,則回傳
null。 -
使用範例:判斷列表是否增加內容;如果增加,則在渲染前將捲軸高度調至更新前的狀態,避免捲軸位置更動。
class ScrollingList extends React.Component { constructor(props) { super(props); this.listRef = React.createRef(); } getSnapshotBeforeUpdate(prevProps, prevState) { // Are we adding new items to the list? // Capture the scroll position so we can adjust scroll later. if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; } return null; } componentDidUpdate(prevProps, prevState, snapshot) { // If we have a snapshot value, we've just added new items. // Adjust scroll so these new items don't push the old ones out of view. // (snapshot here is the value returned from getSnapshotBeforeUpdate) if (snapshot ! null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; } } render() { return ( <div ref={this.listRef}>{/* ...contents... */}</div> ); } }
Lifecycle 設計 Tips
- state initializing 放在
constructor - 獲取外部數據 (加載數據) 放到
componentDidMount或componentDidUpdateAPI
Strict Mode
- 幫忙檢查
- 警告不安全的 lifecycle (棄用的 API)
- 警告 string ref 的使用
- 偵測預期外的 side effect (文長略)
- 警告舊版的 Context API 使用
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<!-- 僅檢查 React.StrictMode 內的元件 -->
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
Change Log
僅節錄目前已使用的部分
DOM
-
Fix minor DOM input bugs in IE and Safari
-
Fix a crash when the input
typechanges from some other types totext -
Fix
onMouseEnterandonMouseLeavefiring on wrong elements -
Correctly detect Ctrl + Enter in
onKeyPressin more browsers
Library
- Warn when defining a non-existent
componentDidReceivePropsmethod - Warn about function child no more than once
- Warn about nested updates no more than once
- Add support for portals in
React.Childrenutilities React.is()Library