🐥 React × TypeScript でのメモアプリ作成 #6 (コンポーネント化・Netlify)
作成日: 2022/02/10
1

学習メモ

コンポーネント化

テキストの追加・表示するところをコンポーネント化

App.tsx

import classes from "../styles/App.module.scss";
import { useState, useRef, FC, useCallback } from "react";
import { InputArea } from "./InputArea";
import { OutputArea } from "./OutputArea";

export const App: FC = () => {
  const inputElement = useRef<HTMLInputElement>(null);
  const [outputText, setOutputText] = useState<string[] | null>([]);

  /*
   * 追加ボタン押下時
   */
  const onClickAddButton = () => {
    if (inputElement.current?.value === "") return; // フォームに入力された文字が空白の場合は何もしない

    // フォームに入力した値を配列に入れる
    const newTexts = [...outputText!, inputElement.current!.value];
    setOutputText(newTexts);

    // フォームに入力した値をリセットする
    inputElement.current!.value = "";
  }

  /*
   * 削除ボタン押下時
   * @param {number} i リストの何番目が押されたかを示す番号
   */
  const onClickDeleteButton = useCallback((i: number) => {
    // 表示されている配列を取得
    const newTexts = [...outputText!];

    // 配列内の該当の要素を削除
    newTexts.splice(i, 1);

    // リストを更新
    setOutputText(newTexts);
  }, [outputText]);

  return(
    <div className={classes.container}>
      <h1 className={classes.title}>簡単メモアプリ</h1>

      <InputArea inputElement={inputElement} onClickAddButton={onClickAddButton} />
      <OutputArea outputText={outputText} onClickDeleteButton={onClickDeleteButton} />

    </div>
  );
};

InputArea.tsx

import classes from "../styles/App.module.scss";
import { FC } from "react";

type Props = {
    inputElement: React.RefObject<HTMLInputElement>;
    onClickAddButton: () => void;
}

export const InputArea: FC<Props> = props => {
    const { inputElement, onClickAddButton } = props;

    return (
        <div className={classes.inputArea}>
        <input ref={inputElement} className={classes.inputAreaTextArea} type="text" placeholder="メモを入力" />
        <button onClick={onClickAddButton} className={classes.inputAreaButton}>追加</button>
      </div>
    )
}

OutPutArea.tsx

import classes from "../styles/App.module.scss";
import { FC } from "react";

type Props = {
    outputText: string[] | null;
    onClickDeleteButton: (i: number) => void;
}

export const OutputArea: FC<Props> = props => {
    const { outputText, onClickDeleteButton } = props;

    return (
        <section className={classes.outputArea}>
            <h2 className={classes.outputAreaTitle}>メモ一覧</h2>
            <ul className={classes.outputAreaList}>
            {
                outputText!.map((listItem: string, i: number) => 
                <li className={classes.outputAreaListItem} key={i}>
                    <span>{listItem}</span>
                    <button onClick={() => onClickDeleteButton(i)}>✕</button>
                </li>          
                )
            }
            </ul>
      </section>
    )
}

Netlifyで公開

CSS Modules を使っているため、デフォルトの設定のままではデプロイできなかった

  1. プロジェクトの Node.js のバージョンを指定
    Environment variablesNODE_VERSION を指定
    ローカルで使用している 14.18.2 にした

  2. Sassを追加
    package.json に以下を追加

"node-sass": "4.14.1"
  1. 完了
    https://quizzical-poitras-f1c0a6.netlify.app/

所感

CSS Modules を使おうとすると、 React.js と Node.js と Sass のバージョンの互換性を考える必要があるため、エラーになりやすいようです。
次に作るときは別の方法でCSSを適用してみようと思います。