🐥
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 を使っているため、デフォルトの設定のままではデプロイできなかった
-
プロジェクトの Node.js のバージョンを指定
Environment variablesでNODE_VERSION
を指定
ローカルで使用している 14.18.2 にした -
Sassを追加
package.json
に以下を追加
"node-sass": "4.14.1"
所感
CSS Modules を使おうとすると、 React.js と Node.js と Sass のバージョンの互換性を考える必要があるため、エラーになりやすいようです。
次に作るときは別の方法でCSSを適用してみようと思います。