1. 程式人生 > >理解 React 高階元件

理解 React 高階元件

1. 什麼是高階元件?

  • 高階元件就是一個函式,它接受另一個元件作為引數,並返回一個新的元件。
  • 當 React 元件被包裹時(warped),高階元件會返回一個增強的 React 元件。
  • 高階元件讓程式碼更具有複用性、邏輯性和抽象特性

2. 為什麼要用高階元件?

  • 在不用高階元件的情況下,寫兩個普通的元件 WelcomeGoodbye ,它們都從 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 就是一個抽象的高階元件,它接受另一個元件作為引數,並返回一個新的元件。高階元件可以對原始元件(傳入元件)進行修飾,這樣在保持單個元件封裝性的同時還保留了易用性。
  • 使用上面的高階元件來簡化 WelcomeGoodbye 元件:
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;
  • 可以看出,高階元件通過 propsusername 傳遞給目標元件,目標元件只管從 props 拿來用就好了,而不需要關心 username 是怎麼來的。