什么是hoc
hoc本质一个函数,接收一个组件返回一个组件
自定义hoc
import React from 'react';
import { Redirect } from 'react-router-dom';
export function withUser(InnerComponent){
return function OuterComponent (props){
let userInfo = localStorage.getItem('userInfo');
try{
userInfo = JSON.parse(userInfo) || {}
}catch(err){
userInfo = {}
}
return (
<InnerComponent user={userInfo} {...props} />
)
}
}
export function withStorage(...keys){
// 返回值才是高阶组件
return function withData(InnerComponent){
// {token:xxx,current:10}
const provide = keys.reduce((prev,key)=>{
let data = localStorage.getItem(key);
try{
data = JSON.parse(data)
}catch(err){
data = data;
}
prev[key] = data
return prev;
},{});
return class OuterComponent extends React.Component{
render(){
return (
<InnerComponent {...provide} {...this.props} ></InnerComponent>
)
}
}
}
}
反向继承 (只适用于类组件,可以拦截生命周期钩子)
export function withAuth(InnerComponent){
class OuterComponent extends InnerComponent{
render(){
console.log('Outer.render');
if(this.props.user.username){
return super.render()
}else{
return <Redirect to="/login" />
}
}
}
OuterComponent = withUser(OuterComponent)
return OuterComponent;
}
// 用户登录权限控制
export function withAuth(InnerComponent){
@withUser
class OuterComponent extends React.Component{
render(){
if(this.props.user.username){
return <InnerComponent {...this.props} />
}else{
return <Redirect to="/login" />
}
}
}
// OuterComponent = withUser(OuterComponent)
return OuterComponent;
}
当然也可在自定义的hoc中使用 react-redux
hoc 代码
import getToken from "./getToken";
import { connect } from "react-redux";
import { loginAction } from "../redux/actions";
// 反向继承
export function withAuth(InnerComponent) {
class OuterComponent extends InnerComponent {
state = {
loginInfo: {}
};
componentDidMount() {
console.log("hoc didMount", this.props);
// super.componentDidMount();
this.getToken();
}
// 获取token
getToken = async () => {
const { token, client } = await getToken();
console.log("token, client", token, client);
let loginInfo = { token, client };
if (token) {
// super.componentDidMount();
this.setState({
loginInfo
});
}
this.props.login(loginInfo);
};
render() {
// console.log("this.state.loginInfo", this.state.loginInfo);
if (this.state.loginInfo.token) {
super.componentDidMount();
}
return (
<InnerComponent {...this.props} loginInfo={this.state.loginInfo} />
);
}
}
// 映射状态
const mapStateToProps = (state) => {
console.log(state);
};
// 映射操作状态的方法
// mapDispatchToProps的简写
const mapDispatchToProps = {
login: loginAction
};
OuterComponent = connect(mapStateToProps, mapDispatchToProps)(OuterComponent);
return OuterComponent;
}
组件代码
import React from "react";
import { connect } from "react-redux";
import { withAuth } from "../utils/hoc";
import { loginAction } from "../redux/actions";
class TestUI extends React.Component {
componentDidMount() {
console.log("test DidMount");
this.getLoginInfo();
}
getLoginInfo = (loginInfo) => {
console.log("获取登录信息", this.props, loginInfo);
console.log("获取登录信息,this.props", this.props);
};
render() {
console.log("test render", this.props);
return <div>我是Test组件</div>;
}
}
const Test2 = withAuth(TestUI);
// 映射状态
const mapStateToProps = (state) => {
console.log("state========", state);
return { lognObj: state };
};
// 映射操作状态的方法
// mapDispatchToProps的简写
const mapDispatchToProps = {};
const Test = connect(mapStateToProps, mapDispatchToProps)(Test2);
export default Test;