函数式组件 -- 触发锁屏

函数式组件 -- 触发锁屏

1. 故事背景

在前端开发中,常常需要实现锁屏功能;最为常见的情况为点击某个按钮进入锁屏。本文从实际业务出发,从已经实现的锁屏功能中抽取出锁屏功能模板,从功能实现和注意细节两个角度进行说明,以实现后续开发过程中的复用。

2. 锁屏活动流程

    1. 点击锁屏按钮
    1. 记录锁屏前的前端路由到本地存储,方便锁屏解除之后回到当前页
    1. 关闭当前页面弹出的所有窗口
    1. 关闭锁屏期间不需要的通信服务,提升性能
    1. 使用react-router-domuseNavigate进行前端路由跳转
    1. 通知后端更新前端的锁屏信息(某些服务可以先暂停,保存时间戳等)

2.1 本地存储方法 setLock2Storage

将锁屏前地址写入本地,方便解除锁屏之后恢复

tsx 复制代码
// 将锁屏前地址写入本地,方便解除锁屏之后恢复
const setLock2Storage = (pathName: string) => {
  // store some info in storage
  sessionStorage.setItem('urlBeforeLock', pathName);
};

2.2 关闭现有弹窗方法 clearModals

父组件通过接口将回调函数队列传入此组件,在clearModals方法中依次执行这些回调函数,逐个关闭打开的Modal

tsx 复制代码
  clearModals(){
    this.props.clearModals?.forEach(cb => void cb());
  }

2.3 锁屏期间关闭和后端不必要的通信服务的方法 clearWs

clearWs方法显然需要从父组件传递过来,直接调用就可以了:this.props.clearWs();

2.4 导航到前端锁屏路由

使用钩子函数``即可完成任务,对于类组件而言,使用适配器设计模式稍微包装一下即可

tsx 复制代码
this.props.navigate("/lock");
...
// 包装组件
const withNavigation = (Component) => {
  return (props) => <Component {...props} navigate={useNavigate()} />;
};
// 暴露包装后的组件
export default withNavigation(Lock);

2.5 发送消息通知后端更新状态的方法 notify

使用的是fetch方法和URL构造函数

tsx 复制代码
// 通知后端更新锁屏状态
const notify = (apiUrl:string, pathName: string) => {
  // send some info to server
  const requestUrl = new URL('/Lock', apiUrl); 
  const requestBody = {
    params: {
      pathName: pathName
    }
  };

  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestBody)
  };

  fetch(requestUrl, requestOptions);
};

2.6 功能内聚方法 handleClick(按钮点击函数的回调)

tsx 复制代码
  handleClick() {
    // 将锁屏前的url存到本地,解除锁屏的时候能够恢复到锁屏之间的位置
    setLock2Storage(this.location);
    // 锁屏之前关闭当前页面上的所有弹窗
    this.clearModals();
    // 锁屏之后和有些ws的通信需要关掉,提高性能
    this.props.clearWs();
    // 导航到锁屏
    this.props.navigate("/lock");
    // 向后端发送请求,更新前端状态
    notify(this.appUri, this.location);
  }

3. Lock组件的接口 -- ILockProps

tsx 复制代码
export interface ILockProps {
  cls4style: string; // 父组件为了控制按钮样式传递过来的类名
  navigate: NavigateFunction; // withNavigation钩子函数向props中注入的方法,作用是进行前端跳转
  clearModals: Array<()=>void>; // 清除当前屏幕上的弹窗
  clearWs: ()=>void; // 关闭锁屏之后不需要通信的ws
  notify: ()=>void; // 通知后端更新前端锁屏状态
}

4. Lock组件的参数

tsx 复制代码
  private appUri = 'http://localhost:3000'; // 后端通讯基地址
  private location = location.pathname; // 当前页路由
  private copywriting = "锁屏"; // 按钮上的文案

5. Lock组件依赖库

tsx 复制代码
import React from "react";
import { Tooltip } from "antd"; // 组件
import { useNavigate } from "react-router-dom"; // 前端路由钩子
import { NavigateFunction } from "react-router/dist/lib/hooks"; // 类型约束

6. Lock组件内容 render函数的返回值

tsx 复制代码
  render() {
    return (
      <Tooltip
        title={this.copywriting}
        placement="top"
      >
        <span
          className={this.props.cls4style}
          onClick={this.handleClick}
          style={{width: 100}}
        >
          {this.copywriting}
        </span>
      </Tooltip>
    );
  }

7. Lock组件全部内容

tsx 复制代码
import React from "react";
import { Tooltip } from "antd";
import { useNavigate } from "react-router-dom";
import { NavigateFunction } from "react-router/dist/lib/hooks";

const withNavigation = (Component) => {
  return (props) => <Component {...props} navigate={useNavigate()} />;
};

export interface ILockProps {
  cls4style: string; // 父组件为了控制按钮样式传递过来的类名
  navigate: NavigateFunction; // withNavigation钩子函数向props中注入的方法,作用是进行前端跳转
  clearModals: Array<()=>void>; // 清除当前屏幕上的弹窗
  clearWs: ()=>void; // 关闭锁屏之后不需要通信的ws
  notify: ()=>void; // 通知后端更新前端锁屏状态
}

// 将锁屏前地址写入本地,方便解除锁屏之后恢复
const setLock2Storage = (pathName: string) => {
  // store some info in storage
  sessionStorage.setItem('urlBeforeLock', pathName);
};

// 通知后端更新锁屏状态
const notify = (apiUrl:string, pathName: string) => {
  // send some info to server
  const requestUrl = new URL('/Lock', apiUrl); 
  const requestBody = {
    params: {
      pathName: pathName
    }
  };

  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestBody)
  };

  fetch(requestUrl, requestOptions);
};
class Lock extends React.Component<ILockProps, undefined> {
  private appUri = 'http://localhost:3000'; // 后端通讯基地址
  private location = location.pathname; // 当前页路由
  private copywriting = "锁屏"; // 按钮上的文案
  
  handleClick() {
    // 将锁屏前的url存到本地,解除锁屏的时候能够恢复到锁屏之间的位置
    setLock2Storage(this.location);
    // 锁屏之前关闭当前页面上的所有弹窗
    this.clearModals();
    // 锁屏之后和有些ws的通信需要关掉,提高性能
    this.props.clearWs();
    // 导航到锁屏
    this.props.navigate("/lock");
    // 向后端发送请求,更新前端状态
    notify(this.appUri, this.location);
  }

  clearModals(){
    this.props.clearModals?.forEach(cb => void cb());
  }
  render() {
    return (
      <Tooltip
        title={this.copywriting}
        placement="top"
      >
        <span
          className={this.props.cls4style}
          onClick={this.handleClick}
          style={{display: 'inline-block',  width: '126px'}}
        >
          {this.copywriting}
        </span>
      </Tooltip>
    );
  }
}

export default withNavigation(Lock);
相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax