首先歡迎你們關注個人Github博客,也算是對個人一點鼓勵,畢竟寫東西無法得到變現,能堅持下去也是靠的是本身的熱情和你們的鼓勵,但願你們多多關注呀!react的部分持續更新中...react
爲何使用高階組件?爲了提升組件複用率,咱們首先想到的是抽離相同的邏輯,在react中就有了HOC(Higher-Order Components)的概念,因此react中的高階組件是用來提升組件複用率的。git
高階組件是一個函數,傳入一個組件,返回另外一個新的組件,產生的新的組件能夠對屬性進行包裝,也能夠重寫部分生命週期。github
高階組件中返回新的組件,能夠是class形式,也能夠是無狀態組件的形式,下面看看高階組件中怎麼返回一個無狀態組件。ajax
如今有一個需求,須要一個組件,傳入某本書的的書名,根據書名獲取到章節,因爲根據書名獲取到章節的這部分邏輯是相同的,因此咱們能夠抽取成爲一個公共組件,這個公共組件就是高階組件。npm
新建src/Hoc.js,裏面定義一個展現某本書章節的無狀態組件Book,props.name爲書名,props.section爲章節:瀏覽器
import React from 'react'
function Book(props) {
return(
<div> { props.name } - { props.section } </div>
)
}
export default Book
複製代碼
在src/index.js中使用該組件,傳入書名,渲染在根節點:bash
import React from 'react';
import ReactDOM from 'react-dom';
import Hoc from './Hoc';
ReactDOM.render(<Hoc name="react"/>, document.getElementById('root')); 複製代碼
還差一個根據書名獲取到章節的高階組件withSection,在Book組件中使用這個高階組件:frontend
function Book(props) {
...
}
const withSection = Com => {
return props => {
const section = '章節 - 高階組件的無狀態組件' // 根據書名props.name獲取到章節section,這裏是模擬數據
return(
<Com {...props} section={section} /> ) } } export default withSection(Book) 複製代碼
這個獲取章節的高階組件傳入的是一個組件Book,返回的是一個無狀態組件,在返回的這個組件中把獲取章節的邏輯處理了,Book原本沒有章節的信息,在使用高階組件後就有了。dom
npm start,瀏覽器輸出函數
react - 章節 - 高階組件的無狀態組件
複製代碼
若是咱們要在高階組件withSection裏面使用生命週期函數,這時候withSection裏面的無狀態組件就不適用了,咱們須要用到class形式的組件。
// 高階組件裏使用生命週期函數
const withSection = Com => {
class GetSection extends Component {
state = {
section: ''
}
componentDidMount() {
// ajax
const section = '章節 - 高階組件的class組件'
this.setState({ section })
}
render() {
return <Com {...this.props} section={this.state.section} /> } } return GetSection } 複製代碼
除了給Book組件加根據書名獲取章節名的高階組件,咱們還想記錄一下用戶閱讀的時間,那應該怎麼辦?高階組件能夠鏈式調用,能夠嵌套多個高階組件,咱們再來定義一個高階組件withUserLog:
const withUserLog = Com => {
class GetUserLog extends Component {
componentDidMount() {
console.log('記錄了用戶的閱讀時間操做')
}
render() {
return <Com {...this.props} /> } } return GetUserLog } 複製代碼
嵌套使用高階組件就好了:
function Book(props) {
...
}
const withSection = Com => {
...
}
const withUserLog = Com => {
...
}
// 鏈式調用
export default withUserLog(withSection(Book))
複製代碼