理解 React 高階元件
阿新 • • 發佈:2019-02-06
1. 什麼是高階元件?
- 高階元件就是一個函式,它接受另一個元件作為引數,並返回一個新的元件。
- 當 React 元件被包裹時(warped),高階元件會返回一個增強的 React 元件。
- 高階元件讓程式碼更具有複用性、邏輯性和抽象特性。
2. 為什麼要用高階元件?
- 在不用高階元件的情況下,寫兩個普通的元件
Welcome
和Goodbye
,它們都從localStorage
中讀取userName
,然後對userName
做一些處理。 Welcome
元件:
import React, {Component} from 'react'
class Welcome extends Component {
constructor(props) {
super(props);
this.state = {
username: ''
}
}
componentWillMount() {
let username = localStorage.getItem('username');
this.setState({
username: username
})
}
render() {
return (
<div>welcome {this.state.username}</div>
)
}
}
export default Welcome;
Goodbye
元件:
import React, {Component} from 'react'
class Goodbye extends Component {
constructor(props) {
super(props);
this.state = {
username: ''
}
}
componentWillMount() {
let username = localStorage.getItem('username' );
this.setState({
username: username
})
}
render() {
return (
<div>goodbye {this.state.username}</div>
)
}
}
export default Goodbye;
- 可以發現, 兩個元件的大部分程式碼都是重複的,這種程式碼冗餘非常不好。
3. 怎麼寫高階元件?
- 我們可以將兩個元件進行抽象,提取公共部分,在公共部分中讀取
userName
, 並將userName
傳遞給具體的元件。改寫如下:
import React, {Component} from 'react'
export default (WrappedComponent) => {
class WrapWithUsername extends Component {
constructor() {
super();
this.state = {
username: ''
}
}
componentWillMount() {
let username = localStorage.getItem('username');
this.setState({
username: username
})
}
render() {
return <WrappedComponent username={this.state.username}/>
}
}
return WrapWithUsername;
}
- 上面的
WrapWithUsername
就是一個抽象的高階元件,它接受另一個元件作為引數,並返回一個新的元件。高階元件可以對原始元件(傳入元件)進行修飾,這樣在保持單個元件封裝性的同時還保留了易用性。 - 使用上面的高階元件來簡化
Welcome
和Goodbye
元件:
import React, {Component} from 'react';
import wrapWithUsername from 'wrapWithUsername';
class Welcome extends Component {
render() {
return (
<div>welcome {this.props.username}</div>
)
}
}
Welcome = wrapWithUsername(Welcome);
export default Welcome;
import React, {Component} from 'react';
import wrapWithUsername from 'wrapWithUsername';
class Goodbye extends Component {
render() {
return (
<div>goodbye {this.props.username}</div>
)
}
}
Goodbye = wrapWithUsername(Goodbye);
export default Goodbye;
- 可以看出,高階元件通過
props
把username
傳遞給目標元件,目標元件只管從 props 拿來用就好了,而不需要關心 username 是怎麼來的。