見出し画像

GAS をローカル環境で開発する - Vol.5 GAS+React 環境実践編

前回の「Vol.4 GAS+React 環境を構築する」では、GAS と React の両方を使ってサンプルが動作するところまできました。

さて、今回は・・・

実際にサイトを作ってみるぞ~!

ということで、ちょっとしたナビゲーション付きのサイトを作ってみようと思います。

ルーティングなども使って、簡単にページ遷移できるようにしてみたいと思います。

では、Let's Go !!

これまでの経緯を知りたい方は、こちらをご覧ください👍



まずはじめに

まずはじめに、最終イメージをもっておきましょう。

・ヘッダーとフッターを横幅いっぱいに表示。
・サイドメニューを左に配置。
・サイドメニューで操作したら、メインコンテンツを更新。

こんな感じで作っていきましょう。

プロジェクト構成

前回の環境構築編で少しお話しましたが、React のプロジェクトをビルドする際 "vite-plugin-singlefile" プラグインを使って 1つのファイル (index.html) にまとめてしまいます。

そのため、GAS のプロジェクトでは、この "index.html" ファイルしか使いません。

混ぜてしまうとわけがわからなくなってしまうので、ここは以下のように分けて管理するようにしています。

Top
┣ gas-app
┃ ┗ index.html   <──────┐ 
┗ react-app    ────────┘ ビルド結果

React のプロジェクト (react-app) のビルド結果を GAS のプロジェクトに渡して、その "index.html" を利用してデプロイするような構成です。

レッツ制作!

まずは最終イメージを作るにあたって、ファイル群を整理しておきましょう。

index.html - インデックスファイル
┗ src
  ┣ main.tsx - ルート
  ┣ App.tsx - アプリケーション本体
  ┣ Header.tsx - ヘッダー
  ┣ Footer.tsx - フッター
  ┣ SideNavBar.tsx - サイドメニューバー
  ┣ MainContents.tsx - メインコンテンツ
  ┣ Home.tsx - ホーム画面
  ┗ Profile.tsx - プロフィール画面

main.tsx

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

これは説明不要ですね。

アプリケーションのエントリーポイントとなるルートを作成しています。
その中で "App" コンポーネントをレンダリングしています。

<React.StrictMode>で不具合を検出しやすくしていますが、実行上は気にする必要はないので「そんなもんだなぁ」ぐらいで留めておいてください。

App.tsx

export default function App() {
  return (<>
  <BrowserRouter>
    <SideNavBar />
    <HeaderBar />
    <MainContents />
    <FooterBar />
  </BrowserRouter>
  </>)
}

アプリケーション本体のレイアウトとルーティングを行っています。

💠ルーティング💠
ユーザーがアクセスした URL に基づいて、表示するページやコンポーネントを決定するプロセスを指します。
SPA (シングルページアプリケーション) の場合は、ページの遷移が行われたとしてもリロードを発生させず、スムーズで早いページ遷移が可能になりユーザーエクスペリエンスが向上します。

Header.tsx

export default function HeaderBar(){
  return(<>
  <div className="topnav">
    <Navbar fixed="top" expand="lg" bg="dark" variant="dark" className="topnav">
      <Navbar.Brand href="">React+GAS サンプル</Navbar.Brand>
    </Navbar>
  </div>
  </>);
}

これは単純にヘッダーを出力しているだけですね。

Footer.tsx

export default function FooterBar(){
  return(<>
  <div id="footer">
    <Navbar fixed="bottom" expand="lg" bg="dark" variant="dark" className="bottomnav">
      <Navbar.Brand href=""2024 Mr.Green</Navbar.Brand>
    </Navbar>
  </div>
  </>);
}

こちらも同じくフッターを表示しているだけです👍

SideNavBar.tsx

function SideNavBar(){
  const navigate = useNavigate();

  const handleNavItemClick = (path: string) => {
    navigate(path);
  };
  
  return(<>
    <StyledDrawer variant="permanent">
      <List>
        <StyledListItem onClick={() => handleNavItemClick('/')}>
          <ListItemIcon>
            <HomeIcon />
          </ListItemIcon>
          <ListItemText primary="ホーム" />
        </StyledListItem>
        <StyledListItem onClick={() => handleNavItemClick('/profile')}>
          <ListItemIcon>
            <AccountCircleIcon />
          </ListItemIcon>
          <ListItemText primary="プロフィール" />
        </StyledListItem>
      </List>
    </StyledDrawer>
  </>);
}

ナビゲーション用のリストを作成し、クリックした際に指定のページにナビゲートしています。

ここでは、Material-UI という人気のフレームワークを使いました。

💠Material-UI とは💠
MUI とも呼ばれる人気のフレームワークです。
美しく一貫性のあるユーザーインタフェースを簡単に構築するためのコンポーネントやツールが提供されています。

⬇️ Material-UI の詳細はこちら ⬇️

引用:https://mui.com/material-ui/

いろんなキレイなパーツ(コンポーネント) が用意されているので、使いやすいですよ✨

MainContents.tsx

export default function MainContents(){
  return(<>
  <div>
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/profile" element={<Profile />} />
    </Routes>
  </div>
  </>);
}

ここでは、ルーティングに従って、メインコンテンツの切り替えを行っています。

"SideNavBar.tsx" で定義されていた

  const navigate = useNavigate();

  const handleNavItemClick = (path: string) => {
    navigate(path);
  };

というハンドラで遷移するようにしていますので、SideNavBar.tsx も一緒に見て下さいね。

Home.tsx / Profile.tsx

export default function Home(){
  return(<>
  <div className="main-contents">
    <p>メインコンテンツ / ホーム</p>
  </div>
  </>);  
}

単純に「メインコンテンツ / ホーム」「メインコンテンツ / プロフィール」と出力しているですので、ちゃんと切り替わっているかどうかの確認用ですね。

レッツビルド!

Reactプロジェクト (react-app) のビルド

まず、React プロジェクト (react-app) でビルドします。

gas-react-sample\react-app> npm run build

> react-app@0.0.0 build
> tsc -b && vite build

vite v5.3.5 building for production...

✓ 1156 modules transformed.
rendering chunks (1)...

../gas-app/src/index.html  306.46 kB │ gzip: 102.19 kB
✓ built in 4.22s

"react-app" フォルダ内で "npm run build" を実行して、
"../gas-app/src/index.html" に出力されていますね。

これを、GASプロジェクトで使用します。

GASプロジェクト (gas-app) の更新とデプロイ

GASプロジェクト (gas-app) を更新します。

gas-react-sample\gas-app> clasp push & clasp deploy

GASプロジェクト側は、単純にページを表示するだけ、しかも、そのページは Reactプロジェクト側で生成されてくるので何もしない、という構造になっていますので、こちらは更新してデプロイするだけですね😅

超簡単✨

デプロイ結果の確認

期待通りの結果ですね✨

GAS で動作させると、最上部に

「このアプリケーションは Google Apps Script のユーザーによって作成されたものです」

という帯が出てしまいます💦
これは、どうやっても消すことはできませんので、放置しておいてください・・・。

さて、次にサイドバーでナビゲーションしてみましょう。

⬇️ ホームボタンを押したところ

⬇️ プロフィールボタンを押したところ

押したボタンのページが "メインコンテンツ" エリアに表示されました!

これで完成です~🎉🎉

ここからはメニューを増やすもよし、メインコンテンツを充実させるもよしで、様々なサイトを構築することができますね。

まとめ

今回が最終回となりましたが、React を使って実践的な GASアプリが作れるようになりました。

どうでしたでしょうか?

GAS って・・・

  • スプレッドシートに処理する関数を追加するだけでしょ。

  • Google の各種アプリと連携するスクリプトでしょ。

といった感じで、今までは裏方の処理 (バックエンド) だと思ってなかったですか?

実は、SaaS (Software as a Service) と見紛うほどのフロントエンドも作れてしまうのです。

面白いでしょ?

ぜひ、この面白さを知って、プログラミングの世界に足を踏み入れてみてくださいね。

自分でいろんなものを作れるようになったら楽しいですよ✨

もちろん、楽しいだけじゃなく、業務効率が向上したり、メリットも極大ですので良いですよね。

今回はココで終わります。

また、プログラミングのお話もしていきたいと思います。

もしわからないことがありましたら、お気軽に LINE公式アカウント でご質問くださいね。

⬇️LINE公式アカウントに登録してご連絡ください⬇️

もし「サポートしたい!」という方がいらっしゃいましたら、ぜひぜひサポートをお願いいたします! 開発費や外注費などクリエイター活動の一部として使用させて頂きます✨