看实例学React hooks

386 阅读1分钟

自定义hook实例一——通用的复制到剪贴板

主要功能:RV组件 提供要复制的内容 www.freecodecamp.org/news/how-to…

useCopyToClipboard.js

import React from "react";
import copy from "copy-to-clipboard";

export default function useCopyToClipboard(resetInterval = null) {
  const [isCopied, setCopied] = React.useState(false);

  // 任何 RV组件的中间处理逻辑都可以被(useCallback)暂存,但只是比较繁复的逻辑才有暂存的价值
  const handleCopy = React.useCallback((text) => {
    if (typeof text === "string" || typeof text == "number") {
      copy(text.toString());
      setCopied(true);
    } else {
      setCopied(false);
      console.error(
        `Cannot copy typeof ${typeof text} to clipboard, must be a string or number.`
      );
    }
  }, []);

// 给RV组件安装定时器,理解比较高级一点
// 定时清除剪贴板的内容
  React.useEffect(() => {
    let timeout;
    if (isCopied && resetInterval) {
      timeout = setTimeout(() => setCopied(false), resetInterval);
    }
    return () => {
      clearTimeout(timeout);
    };
  }, [isCopied, resetInterval]);

  return [isCopied, handleCopy];
}

CopyButton.js

  • 1 这个“复制按键”UI 本没有 「复制到剪贴板」的代码或功能
  • 2 hook只简单用一条件语名 useCopyToClipboard,和两个接口(isCopied, handleCopy),将功能“勾”了进来
  • 3 看,useCopyToClipboard 的代码,就是好像内置入CopyButton一样
    • L useCopyToClipboard 的代码是「标准的 RV组件代码」,只是不完整
  • 4 从这往后推理,其实,useState, useEffect 也是一些基础,但也是标准RV组件代码,只是非常的通用,被“勾”了进来
import React from "react";
import ClipboardIcon from "../svg/ClipboardIcon";
import SuccessIcon from "../svg/SuccessIcon";
import useCopyToClipboard from "../utils/useCopyToClipboard";

function CopyButton({ code }) {
  // isCopied is reset after 3 second timeout
  const [isCopied, handleCopy] = useCopyToClipboard(3000);

  return (
    <button onClick={() => handleCopy(code)}>
      {isCopied ? <SuccessIcon /> : <ClipboardIcon />}
    </button>
  );
}