高阶组件应用

#积累/react

抽取组件内部状态

  • 弹窗组件
    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
    export function bindPopupTrigger(Children){
    return class PopupTrigger extends Component {
    constructor(props){
    super(props)
    this.state = {
    popData: {
    isOpen: false,
    msg: 'hello',
    jump: '',
    btnTxt: '确定'
    }
    }
    this.changePopData = this.changePopData.bind(this)
    this.popClose = this.popClose.bind(this)
    }
    popClose(){
    const {popData} = this.state;
    this.setState({
    popData:{
    ...popData,
    isOpen: false
    }
    })
    }
    changePopData({msg,jump,btnTxt}){
    console.log(msg,jump,btnTxt)
    this.setState({
    popData:{
    isOpen: true,
    msg,
    jump,
    btnTxt,
    }
    })
    }
    render(){
    const {popData} = this.state;
    return <div>
    <Children changePopData={this.changePopData}/>
    <PopUp {...popData} onClose={this.popClose}/>
    </div>
    }
    }
    }
  • 抽取输入框state
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    const MyContainer = WrappedComponent =>
    class extends Component {
    constructor (props) {
    super (props);
    this.state = {
    name: '',
    };
    this.onNameChange = this.onNameChange.bind (this);
    }
    onNameChange (event) {
    this.setState ({
    name: event.target.value,
    });
    }
    render () {
    const newProps = {
    name: {
    value: this.state.name,
    onChange: this.onNameChange,
    },
    };
    return <WrappedComponent {...this.props} {...newProps} />;
    }
    };

接口数据的请求

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
import ShopList from '../components/ShopList.jsx';

function shopListWithFetching(fetchData, defaultProps) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentWillMount() {
fetchData().then((list) => {
this.setState({
data: list,
});
}, (error) => {
console.log(error); // eslint-disable-line
});
}
render() {
return <ShopList data={this.state.data} {...defaultProps} {...this.props} />;
}
};
}
export default shopListWithFetching;

登陆态判断

登陆态的判断抽离到高阶组件
还可以搭配React生命周期、接口请求处理更复杂情况

1
2
3
4
5
6
7
8
9
10
11
const withLogin = (Component) => {
const NewComponent = (props) => {
if (getUserId()) {
return <Component {...props} />;
} else {
return null;
}
}

return NewComponent;
};

鉴权

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
import React from 'react';
import { whiteListAuth } from '../lib/utils';

/**
* 白名单权限校验
* @param WrappedComponent
* @returns {AuthWrappedComponent}
* @constructor
*/
function AuthWrapper(WrappedComponent) {
class AuthWrappedComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
permissionDenied: -1,
};
}
componentWillMount() {
whiteListAuth().then(() => {
// success
this.setState({
permissionDenied: 0,
});
}, (error) => {
this.setState({
permissionDenied: 1,
});
console.log(error);
});
}
render() {
if (this.state.permissionDenied === -1) {
return null;
}
if (this.state.permissionDenied) {
return <div>功能即将上线,敬请期待~</div>;
}
return <WrappedComponent {...this.props} />;
}
}

return AuthWrappedComponent;
}

export default AuthWrapper;

日志及性能打点

组件包裹上PV、UV等统计功能。