在近期的项目中有个需求:当用户注册账号,登录系统后,需要完善个人信息。只有在完善了个人信息后,才能访问某些特定的页面,否则出现让用户补全资料的提示,如下图:

由于有多个页面都需要用户完善资料后才能访问,我想到写一个通用的继承型高阶组件来实现这个功能:这个继承型高阶组件继承于页面级组件,渲染时根据用户是否补全了资料决定渲染父类页面级组件的内容或是要求用户补全资料的提示内容。
这个高阶组件的定义如下:
import React from "react";
import { Link } from "react-router-dom";
import { ROLE_STATE } from "@/shared/constant";
import style from "./style.m.less";
export function linkGuardHOC(PageComponent){
return class ExtendHOC extends PageComponent{
render(){
const shopId = localStorage.getItem("__xxx_auth_shop_id");
const userType = +localStorage.getItem("__xxx_auth_user");
if(
userType === ROLE_STATE.get("ADMIN") ||
shopId;
) return super.render();
return (
<section className={style.contentWrap}>
<div></div>
<p>Sorry,您还没有完善资料,无法进行此操作哦~</p>
<p>请前往<Link to="/shopInfo">完善资料</Link></p>
</section>
);
}
};
}
当用户角色为管理员或者已经补全资料后,渲染父类组件的内容,否则渲染完善资料的引导页面。
生命周期的处理
单从页面展示这一角度来说,上面的组件已经完成我们想要的功能。但我们还需要对生命周期方法进行处理。具体来说,我在页面级组件中,初始化请求数据放在 componentWillMount
这个生命周期方法中,当用户没有补全资料时,除了在展示要求补全资料的引导页外,还需要阻止初始化的数据请求,否则后台接口会因为资料不全返回错误信息,展示在页面上。

这时,我们就需要对子类的 componentWillMount
方法进行重写:
import React from "react";
import { Link } from "react-router-dom";
import { ROLE_STATE } from "@/shared/constant";
import style from "./style.m.less";
export function linkGuardHOC(PageComponent){
return class ExtendHOC extends PageComponent{
constructor(props){
super(props);
}
componentWillMount(){
const shopId = localStorage.getItem("__xxx_auth_shop_id");
const userType = +localStorage.getItem("__xxx_auth_user");
this.shopId = shopId;
this.userType = userType;
this.renderFlag = this.userType === ROLE_STATE.get("ADMIN") || this.shopId;
if(this.renderFlag) super.componentWillMount();
}
render(){
if(this.renderFlag) return super.render();
return (
<section className={style.contentWrap}>
<div></div>
<p>Sorry,您还没有完善资料,无法进行此操作哦~</p>
<p>请前往<Link to="/shopInfo">完善资料</Link></p>
</section>
);
}
};
}
只有在用户补全资料后才调用父类的 componentWillMount
方法初始化数据,否则不作处理。
总结
React 真是一个厉害的框架,将函数式编程和面向对象编程进行了集成,得益于 JavaScript 极高的灵活性,可以编写出非常优美实用的代码。
完。
网友评论