はじめに
TypescriptとReactでテキストをコピーするボタンの実装をしてみます。
CopyButtonの実装
クリップボードへのコピー部分に関しては下記のclipboard-copy
を利用します。

clipboard-copy
Lightweightcopytoclipboardfortheweb.Latestversion:4.0.1,lastpublished:3yearsago.Startusingclipboard-copyinyourprojectbyrunning`npmiclipboard-copy`.Thereare272ot...
テキストをコピーするボタンの実装内容は下記の通りです。
"use client"
import copy from "clipboard-copy"
import { useState } from "react"
const CopyButton = ({ copyText }: { copyText: string }) => {
const [isCopied, setIsCopied] = useState(false)
const handleCopy = () => {
copy(copyText).then(() => {
setIsCopied(true)
setTimeout(() => {
setIsCopied(false)
}, 3000)
})
}
return (
<button disabled={isCopied} onClick={handleCopy}>
{isCopied ? "Copied!" : "Copy"}
</button>
)
}
export default CopyButton
isCopied
でコピーしたかどうかを判定して、コピーボタンに表示されたボタンをCopu
からCopied!
に変化させています。Copied!
の文字は3秒(3000ミリ秒)後にCopy
に戻るようになっています。
Next.jsで実装してみる
実際にNext.jsを使ってコピーボタンを実装してみます。
まずはNext.jsで新しいアプリケーションを作成します。
npx create-next-app@latest
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
✔ What is your project named? … copy-button
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias? … No / Yes
アプリケーションのディレクトリに移動して、clipboard-copy
もインストールしておきます。
cd copy-button
npm install clipboard-copy
public配下のsvgファイルはいらないので削除してしまいます。
rm public/*.svg
CopyButton.tsx
を配置するディレクトリを作成します。
mkdir src/components
CopyButton.tsx
は下記の通りです。
"use client"
import copy from "clipboard-copy"
import { useState } from "react"
const CopyButton = ({ copyText }: { copyText: string }) => {
const [isCopied, setIsCopied] = useState(false)
const handleCopy = () => {
copy(copyText).then(() => {
setIsCopied(true)
setTimeout(() => {
setIsCopied(false)
}, 3000)
})
}
return (
<button disabled={isCopied} onClick={handleCopy}>
{isCopied ? "Copied!" : "Copy"}
</button>
)
}
export default CopyButton
src/app/page.tsx
は余分なコードを削除して、下記のようにして試してみます。textList
の文字列をそれぞれ表示して、コピーボタンでコピーできるようにしています。
import CopyButton from "../components/CopyButton"
export default function Home() {
const textList: string[] = ["text1", "text2", "text3"]
return (
<div className="p-20">
{textList.map((text, index) => (
<span key={index} className="m-2">
<div className="relative flex justify-between w-auto p-4 bg-gray-600 rounded-lg">
<pre className="overflow-x-auto text-white py-2">{text}</pre>
<CopyButton copyText={text} />
</div>
</span>
))}
</div>
)
}
準備ができたので、ローカルでアプリケーションを起動してみます。
npm run dev
localhost:3000
にアクセスすると下記のようにコピーボタンがそれぞれ表示されていることが確認できます。
Copy
をクリックすると、対象のテキストがクリップボードにコピーされて、ボタンがCopied!
に変わっているのが確認できます。