npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-khooks

v1.2.4

Published

This is a custom hook based on React keyboard events, integrating event queue management solutions

Downloads

12

Readme

react-khooks

Getting Started

📦 Install

$ npm i react-khooks --save

🔨 Usage

// 根据需要结构以下对应模块使用
import { useKeyEvent } from 'react-khooks'; //键盘hooks
import { emitter } from 'react-khooks'; //事件队列中心(单例)

这是一个基于React的键盘事件的自定义hooks,是基于公司的业务封装的,支持一个按键绑定多个事件(事件队列管理),只触发最新绑定的事件,队列顺序根据业务去维护,毕竟正常来说一个按键在某一时刻只会触发单一功能事件。(其实可以通过事件权重去托管给emitter本身去管理)

tips: 已重构为ts(菜鸡)版本,欢迎star和issue

| 参数 | 说明 | | --- | --- | | keyName | 键盘按键名key或keyCode,建议统一,必传(组合键使用+连接,如:ctrl+按键名,请注意和浏览器以及系统按键的冲突问题) | | callback | 回调函数,默认参数e为KeyboardEvent事件对象,必传 | | toolEventName | 自定义事件名称,作为该键盘事件队列中的唯一标识,必传 | | type | 键盘弹起或按下(keyup/keydown),默认keyup | | delayTime | 防抖/节流延迟时间,默认0为不使用节流/防抖 (如果使用keydown,建议设置) | | delayType | 1节流/2防抖,默认1 |

  • 一般来说,你只需要传入三个属性:keyName(键盘按键名),callback(回调函数),toolEventName(自定义事件名)
  • 支持复合键+按键和**复合键+复合键+按键的组合按键事件 (复合键是指ctrl/alt/shift)
  • 你可以基于callback的默认参数KeyboardEvent根据该事件对象进行更多逻辑控制或完成更多复合按键
  • useKeyEvent默认返回事件队列实例,这是一个单例,意味着你在任何地方返回的都是同一个emitter实例或者直接导入,以手动控制事件队列

基本用法:

import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const handleClick = () => {
    alert('按键z触发');
  };

  useKeyEvent({ keyName: 'z', callback: handleClick, toolEventName: 'alert' });

  return (
    <div>
      <div>按键z键弹出提示</div>
    </div>
  );
};

组合键(ctrl/alt/shift+按键):

  • 回调接收默认参数(KeyboardEvent 事件对象)
import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);
  const handleClick = (e) => {
    setNum(num + 1);
  };
  useKeyEvent({ keyName: `alt+v`, callback: handleClick, toolEventName: '增加num' });
  useKeyEvent({ keyName: `ctrl+v`, callback: handleClick, toolEventName: '增加num' });
  useKeyEvent({ keyName: `shift+v`, callback: handleClick, toolEventName: '增加num' });

  return (
    <div>
      <div>按键ctrl/alt/shift+v增加num</div>
      <span>num: {num}</span>
    </div>
  );
};

动态切换绑定热键:

import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);
  const [hotKey, setHotKey] = useState('m');
  const handleClick = () => {
    setNum(num + 1);
  };

  useKeyEvent({ keyName: hotKey, callback: handleClick, toolEventName: '修改num' });

  return (
    <div>
      <div>按键{hotKey}键修改num</div>
      <div>num: {num}</div>
      <div>
        <button onClick={() => setHotKey('n')}>切换为使用n键修改num</button>
      </div>
    </div>
  );
};

节流/防抖

import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);
  const handleClick = useCallback(() => {
    setNum(num + 1);
  }, [num]);
  useKeyEvent({
    keyName: 'q',
    callback: handleClick,
    toolEventName: '长按q键修改num',
    delayTime: 500,
    type: 'keydown',
    delayType: 1,
  });
  useKeyEvent({
    keyName: 'w',
    callback: handleClick,
    toolEventName: '长按w键修改num',
    delayTime: 500,
    type: 'keydown',
    delayType: 2,
  });

  return (
    <div>
      <div>节流:长按q键修改num(每500ms触发一次)</div>
      <div>num: {num}</div>
      <div>防抖:长按w键修改num(直到抬起触发一次)</div>
    </div>
  );
};

关于回调函数 callback 的处理强烈建议使用 useCallback,避免组件重新渲染时频繁订阅取消

  • 使用 useCalback 内 setState 获取当前状态
import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);

  const handleClick = useCallback(() => {
    setNum((num) => num + 1);
  }, []);

  useKeyEvent({ keyName: 'a', callback: handleClick, toolEventName: 'add' });

  return (
    <div>
      设置快捷键 a 修改 useState 定义的 num 数据
      <div>num: {num}</div>
    </div>
  );
};
  • useCallback 依赖获取当前状态
import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);

  const handleClick = useCallback(() => {
    setNum(num - 1);
  }, [num]);

  useKeyEvent({ keyName: 's', callback: handleClick, toolEventName: 'reduce' });

  return (
    <div>
      设置快捷键 s 修改 useState 定义的 num 数据
      <div>num: {num}</div>
    </div>
  );
};
  • ~~不推荐(会导致组件重新渲染时频繁取消/订阅,性能差,虽然内部做了处理,避免这个问题,但是还是不推荐)~~
  • 目前做了优化,组件重新渲染时不会频繁取消/订阅(虽然好像可以在回调中拿到最新的state,但还是推荐使用前门两种方式获取state)
import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);
  const handleClick = (param) => {
    setNum(num + param);
  };

  useKeyEvent({ keyName: 'ctrl+x', callback: () => handleClick(1), toolEventName: 'add_2' });
  useKeyEvent({ keyName: 'shift+x', callback: () => handleClick(-1), toolEventName: 'reduce_2' });

  return (
    <div>
      <div>按键ctrl+x增加num</div>
      <div>按键shift+x减小num</div>
      <button onClick={() => handleClick(1)}> 加 1 </button>
      <span>num: {num}</span>
      <button onClick={() => handleClick(-1)}> 减 1 </button>
    </div>
  );
};

freezeAll/unfreezeAll:冻结/解冻所有键盘事件队列

import React, { useState, useCallback } from 'react';
import { useKeyEvent } from 'react-khooks';

export default () => {
  const [num, setNum] = useState(0);

  const handleClick = () => {
    setNum((num) => num + 1);
  };

  const { emitter } = useKeyEvent({ keyName: 'f', callback: handleClick, toolEventName: 'add' });
  // 你也可以直接 import { emitter } from 'react-khooks',因为这里的emitter始终是同一个实例

  return (
    <div>
      <p>按下键盘f键修改num</p>
      <span style={{ border: '1px solid #ccc' }} onClick={() => emitter.freezeAll()}>
        冻 结
      </span>
      <div>num: {num}</div>
      <span style={{ border: '1px solid #ccc' }} onClick={() => emitter.unfreezeAll()}>
        解 冻
      </span>
    </div>
  );
};