ユニバーサル Web アプリケーション

ユニバーサル Web アプリケーション の構築へと進む。

怒涛のごとく専門用語とその定義が紹介されている。

今時の Web アプリケーション のことでしょとゆるふわな理解で先に進むぞ。

技術選定として、 UI ライブラリに React 。アプリケーションフレームワークNext.js を利用。

簡単な例を通して実装の詳細に依存しない概要を説明します。

著者の想定する読者層の簡単はどの程度高度なのか?震えながら読むこととする。

アプリケーションは、 Web アプリケーション のルーティングを確認するために「/で、すべての ToDo」、「/active で、未完了 Todo」、「/completed で、完了済 ToDo」と実装する。

ハンズオン Node.js のリポジトリ でバージョンを確認後インストール。

npm i react@16.13.1 react-dom@16.13.1 next@9.4.2

コードを一部変更して、自分なりに理解してきました。でもこの章は無理です。 書籍「ハンズオン Node.js」に書かれたコードを追うことすらままならない。

簡単ではあるがコードの解説はされている。なので、雰囲気ではわかったような気がする。 しかし、 Material-UITailwindcss を使ってさくっとすてきな見た目に変更したくても、どこからどのようにはじめてよいのかわからない。

そして、ルーティングに Next.js を用いている。わからない度合いが更に深まる。

どのような UI を考えたか

  1. li タグの行頭のマーカーを消去
  2. 各 ToDo 毎に checkbox を付ける
  3. 初期 completedtrue/false によりチェック有無を切り替え
  4. checkbox のクリックイベントとリクエストの put/delete を紐付ける
  5. イベントに応じて line-through/none を切り替える

結果としては、3,4,5 のコーディングができない。

f:id:mendels:20210106051232p:plain
挫折 ToDoアプリケーションUIの変更

import { useEffect, useState } from 'react';
import Link from 'next/link';
import Head from 'next/head';
import 'isomorphic-fetch';

const pages = {
  index: { title: 'すべてのToDo', fetchQuery: '' },
  active: { title: '未完了のToDo', fetchQuery: '?completed=false' },
  completed: { title: '完了したToDo', fetchQuery: '?completed=true' },
};
const pageLinks = Object.keys(pages).map((page, index) => (
  <Link href={`/${page === 'index' ? '' : page}`} key={index}>
    <a style={{ marginRight: 10 }}>{pages[page].title}</a>
  </Link>
));

export default function Todos(props) {
  const { title, fetchQuery } = pages[props.page];
  const [checked, setChekced] = useState(false);

  const [todos, setTodos] = useState([]);
  useEffect(() => {
    fetch(`/api/todos${fetchQuery}`).then(async (res) =>
      res.ok ? setTodos(await res.json()) : alert(await res.text())
    );
  }, [props.page]);

  return (
    <>
      <Head>
        <title>{title}</title>
      </Head>
      <h1>{title}</h1>
      <ul style={{ listStyle: 'none' }}>
        {todos.map(({ id, title, completed }) => (
          <li key={id}>
            <label>
              <input
                style={{ marginRight: '0.8em' }}
                type="checkbox"
                value={checked}
                onChange={() => setChekced(!checked)}
              />
              <span style={completed ? { textDecoration: 'line-through' } : {}}>{title}</span>
            </label>
          </li>
        ))}
      </ul>
      <div>{pageLinks}</div>
    </>
  );
}

できなかった残念なコードを晒しておく。 いつか未来のどこかで、昔はこのような簡単なこともわからなかったと思い出にひたれるだろうか?

章末の練習問題は、どうにかこなした。 DELETE リクエストを VS CodeREST Client で投げる方法がわからない。

まとめとしては、「完全に挫折した」です。

リファレンス

今回利用した API のリファレンス。

Next.js リファレンス

next/link

next/head

React.js リファレンス

useEffect

useState