【Typescript】Reactでテキストをコピーするボタンを実装する

2023.07.30
2024.03.24
プログラミング
Next.jsReactTypescript

はじめに

TypescriptとReactでテキストをコピーするボタンの実装をしてみます。

CopyButtonの実装

クリップボードへのコピー部分に関しては下記のclipboard-copyを利用します。

clipboard-copy

clipboard-copy

Lightweight copy to clipboard for the web. Latest version: 4.0.1, last published: 4 years ago. Start using clipboard-copy in your project by running `npm i clipboard-copy`. There are 305 other projects in the npm registry using clipboard-copy.

テキストをコピーするボタンの実装内容は下記の通りです。

1"use client"
2import copy from "clipboard-copy"
3import { useState } from "react"
4
5const CopyButton = ({ copyText }: { copyText: string }) => {
6  const [isCopied, setIsCopied] = useState(false)
7
8  const handleCopy = () => {
9    copy(copyText).then(() => {
10      setIsCopied(true)
11      setTimeout(() => {
12        setIsCopied(false)
13      }, 3000)
14    })
15  }
16
17  return (
18    <button disabled={isCopied} onClick={handleCopy}>
19      {isCopied ? "Copied!" : "Copy"}
20    </button>
21  )
22}
23export default CopyButton

isCopiedでコピーしたかどうかを判定して、コピーボタンに表示されたボタンをCopuからCopied!に変化させています。Copied!の文字は3秒(3000ミリ秒)後にCopyに戻るようになっています。

Next.jsで実装してみる

実際にNext.jsを使ってコピーボタンを実装してみます。

まずはNext.jsで新しいアプリケーションを作成します。

1npx create-next-app@latest
1Need to install the following packages:
2  [email protected]
3Ok to proceed? (y) y
4✔ What is your project named? … copy-button
5✔ Would you like to use TypeScript? … No / Yes
6✔ Would you like to use ESLint? … No / Yes
7✔ Would you like to use Tailwind CSS? … No / Yes
8✔ Would you like to use `src/` directory? … No / Yes
9✔ Would you like to use App Router? (recommended) … No / Yes
10✔ Would you like to customize the default import alias? … No / Yes

アプリケーションのディレクトリに移動して、clipboard-copyもインストールしておきます。

1cd copy-button
2npm install clipboard-copy

public配下のsvgファイルはいらないので削除してしまいます。

1rm public/*.svg

CopyButton.tsxを配置するディレクトリを作成します。

1mkdir src/components

CopyButton.tsxは下記の通りです。

1"use client"
2import copy from "clipboard-copy"
3import { useState } from "react"
4
5const CopyButton = ({ copyText }: { copyText: string }) => {
6  const [isCopied, setIsCopied] = useState(false)
7
8  const handleCopy = () => {
9    copy(copyText).then(() => {
10      setIsCopied(true)
11      setTimeout(() => {
12        setIsCopied(false)
13      }, 3000)
14    })
15  }
16
17  return (
18    <button disabled={isCopied} onClick={handleCopy}>
19      {isCopied ? "Copied!" : "Copy"}
20    </button>
21  )
22}
23export default CopyButton

src/app/page.tsxは余分なコードを削除して、下記のようにして試してみます。textListの文字列をそれぞれ表示して、コピーボタンでコピーできるようにしています。

1import CopyButton from "../components/CopyButton"
2
3export default function Home() {
4  const textList: string[] = ["text1", "text2", "text3"]
5
6  return (
7    <div className="p-20">
8      {textList.map((text, index) => (
9        <span key={index} className="m-2">
10          <div className="relative flex justify-between w-auto p-4 bg-gray-600 rounded-lg">
11            <pre className="overflow-x-auto text-white py-2">{text}</pre>
12            <CopyButton copyText={text} />
13          </div>
14        </span>
15      ))}
16    </div>
17  )
18}

準備ができたので、ローカルでアプリケーションを起動してみます。

1npm run dev

localhost:3000にアクセスすると下記のようにコピーボタンがそれぞれ表示されていることが確認できます。

Copyをクリックすると、対象のテキストがクリップボードにコピーされて、ボタンがCopied!に変わっているのが確認できます。

参考

Support

\ この記事が役に立ったと思ったら、サポートお願いします! /

buy me a coffee
Share

Profile

author

Masa

都内のIT企業で働くエンジニア
自分が学んだことをブログでわかりやすく発信していきながらスキルアップを目指していきます!

buy me a coffee