【Laravel + React】クリップボードにコピーできるボタンをつくる

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、Reactが提供するHookの便利さに触れて感動する毎日を送っています。(もしかすると、昔Reactが使いにくいと感じたのはHookがなかったからかもしれません)

そして、そうなると過去にVuejQueryで作った機能もReactでやってみたくなってきました。

そんなこともあって今回のテーマはこちら❗

クリップボードにコピーできるボタンをつくる

です。

機能としては「テキストをクリップボードにコピーし、貼り付けができるようにする」というものですが、こういった機能は便利ですよね。

ちなみに、我々開発者がよく見る場面でいうと、ウェブサービスの「APIキー」を取得するときが多いんじゃないでしょうか。

そこで❗

今回はLaravel + Reactをつかって「クリップボードにコピーできるボタン」を実装してみたいと思います。

ぜひ何かの参考になりましたら嬉しいです。😄✨

「メモリ8 → 16 GB
でバク速PC環境に❗
もうnpmは怖くない👍」

開発環境: Laravel 9.x、React、Vite、Inertia.js、TailwindCSS

ルートをつくる

では、まずはルートからです。
今回もひとつだけなのでコントローラーはつくらず、省略形で書いています。

routes/web.php

use Inertia\Inertia;

// 省略

Route::get('copy_to_clipboard', fn() => Inertia::render('CopyToClipboard/Index'));

ビューをつくる

そして、ブラウザで実際に表示される部分の「ビュー(テンプレート)」をつくります。

resources/js/Pages/CopyToClipboard/Index.jsx

import {useState} from 'react';
import CopyToClipboard from '@/Components/CopyToClipboard';

export default function Index() {

    // Data
    const [text1, setText1] = useState('ビール');
    const [text2, setText2] = useState('ワイン');
    const [text3, setText3] = useState('日本酒');
    const texts = [text1, text2, text3];

    // Methods
    const handleClick = () => {

        setText1('ラーメン');
        setText2('カレー');
        setText3('牛丼');

    };
    const handleCopy = text => {

        console.log(`「${text}」がコピーされました`);

    };

    return (
        <div className="p-5">

            <h1 className="font-bold mb-5">【Laravel + React】クリックでクリップボードにコピーできるボタン</h1>

            <small className="text-gray-500">コピー内容</small>
            {texts.map((text, index) => (
                <div key={index}>
                    {index+1}.{text}
                </div>
            ))}
            <div className="mt-3">
                <a href="#" className="underline text-blue-700 text-sm" onClick={handleClick}>コピー内容を変更</a>
            </div>

            <hr className="my-5" />

            {/* 基本 */}
            <div className="mb-5">
                <CopyToClipboard text={text1} onCopy={text => handleCopy(text)} />
            </div>

            {/* クラスを変更 */}
            <div className="mb-5">
                <CopyToClipboard
                    text={text2}
                    className="bg-red-500 text-white font-bold py-1.5 px-2.5 rounded-lg"
                    onCopy={text => handleCopy(text)}></CopyToClipboard>
            </div>

            {/* ラベルを変更 */}
            <div className="mb-10">
                <CopyToClipboard text={text3} onCopy={text => handleCopy(text)}>
                    <small>&#x1F4CB; クリップボードへコピー</small>
                </CopyToClipboard>
            </div>

            <input type="text" placeholder="貼り付け確認用" />

        </div>
    );

}

なお、今回は以下のボタンを3つ作っています。(コンポーネントは共通のものです)

  • 通常ボタン
  • クラスを変更する(赤いボタンでよりカーブがきつい形)
  • ボタンのラベル(テキスト)を変更し、絵文字も使う

コンポーネントをつくる

続いて、さっきの「ビュー」で使ったCopyToClipboardコンポーネントをつくっていきます。

これが今回のメイン部分です。

resources/js/Components/CopyToClipboard.jsx

import {useState} from 'react';

export default function CopyToClipboard(props) {

    // Data
    const copyingText = props.text;
    const buttonClassNames = props.className || 'bg-blue-500 text-white font-bold py-2 px-4 rounded';
    const originalButtonLabel = props.children || 'コピーする';
    const [buttonLabel, setButtonLabel] = useState(originalButtonLabel);

    // Methods
    const handleClick = () => {

        navigator.clipboard.writeText(copyingText); // 注: https でしか使えません
        setButtonLabel('完了!');

        setTimeout(() => {

            setButtonLabel(originalButtonLabel);

            if(typeof props.onCopy ==='function') {

                props.onCopy(copyingText);

            }

        }, 700);

    };

    return (
        <button className={buttonClassNames} onClick={handleClick}>
            {buttonLabel}
        </button>
    );

}

とてもコードとしては短いですよね。
今回は「こんなに短くても便利な機能が実装できるよ」というのを実感していただけたら嬉しいです😄

なお、中身としては「クリックされたらクリップボードへコピーする」だけなのですが、そのときにボタンのラベル(テキスト)を変更するためuseState()を使っています。

ちなみに

もしhttpでもコピーを実装したい場合は以下のページを参考にしてみてくだい。(題材はVueですが、コピー部分のロジックはまったく同じです)

📝 Vue 3 でクリップボードにコピーできるボタンをつくる

テストしてみる

では、実際にテストしてみましょう❗(動画版は こちら

まずViteを起動し「https://******/copy_to_clipboard」へアクセスします。(コピーが必要なのでHTTPSでアクセスします)

3つのボタンの表示が違っています。
まずはうまくいっています👍

では、次に一番上の「コピーする」ボタンをクリックしてみます。

すると・・・・・・

ボタンのテキストが変わりましたので、以下の確認用入力ボックスに「Ctrl + V」で貼り付けてみましょう。

どうなるでしょうか。

はい❗
予定していたとおり「ビール」がクリップボードに保持されていました。

では、続いて「コピー内容を変更」リンクをクリックして、コピーする内容を変更してみます。

クリックすると・・・・・・??

はい、表示(変数の中身)が変わりました。

では、この状態で今度は赤のボタンをクリックしてみます。

以下のように完了ボタンが出て・・・・・

ペーストしてみると・・・・

はい❗
今回は表示変更後の2つめ「カレー」がコピペできました。

すべて成功です😄✨

デモページを用意しました

せっかくなのでデモページを用意しました。
ぜひ実際に触ってみてください👍

📝 デモページ

企業様へのご提案

今回のようにちょっと便利な機能をコンポーネント化しておくと、再度同じコードを書く必要がなくなり、開発を効率化することができます。

もしそういったご希望がございましたら、いつでもお気軽にご相談ください。

お待ちしております。😄✨

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はLaravel + Reactで「クリップボードへコピーできるボタン」を作ってみました。

ちなみに今回はコピー機能を有効にするためにhttpsでブラウザからアクセスしましたが、そうなるとViteの「オートリロード機能」が動かなくなってしまいました。(コンソールにもエラーが出ていました)

このあたりは今後調査し、何かわかりましたら後日追って報告したいと思います。

ではでは〜❗

「姪っ子がくれた
手紙に心から感動😂」

このエントリーをはてなブックマークに追加       follow us in feedly