はじめに
Reactで簡易的な学習記録アプリを開発しました。
開発をした中での気づきと振り返りをまとめます。
作ったアプリについて
機能詳細
【使用言語】React 19.2.8
【開発環境】vite 8.2.2
【開発期間】約3日
CSSでスタイリングはせず、最低限の機能のみを実装しました。
- 入力内容のリアルタイム反映
- 未入力のエリアがあったらエラー表示とボタンを非活性にする
- 学習内容と学習時間の登録と表示
- 合計学習時間の表示
振り返り
結構苦戦しました。console.logで値を1つずつ確認しながら進めて行きましたが、どうしても分からなかったところはChatGPTに教えてもらいました。以下は特に実装に苦戦した機能です。
バリデーション・エラーハンドリング
学習内容と学習時間の入力エリアのどちらかが未入力だった場合はエラー表示させるという機能を実装するために以下のコードを書いたのですが、これが上手く行きませんでした。(全て書くと長くなるのでコードは該当部分だけにしてます)
// 学習内容を管理するステート
const [contents, setContents] = useState("");
// 学習時間を管理するステート
const [time, setTime] = useState(0);
// エラーを管理するステート
const [hasError, setHasError] = useState(true);
// onChangeイベントハンドラ:入力された学習内容を取得する
const handleContentsChange = (e) => {
setContents(e.target.value);
validateForm();
};
// onChangeイベントハンドラ:入力された学習時間を取得する
const handleTimeChange = (e) => {
setTime(Number(e.target.value));
validateForm();
};
// 入力エリアをチェックする関数
const validateForm = () => {
if (contents === "" || time === 0 || time === "") {
setHasError(true);
} else {
setHasError(false);
}
};
// 学習内容入力エリア
<input
type="text"
value={contents}
onChange={handleContentsChange}
/>
// 学習時間入力エリア
<input
type="num"
min="0"
value={time}
onChange={handleTimeChange}
/>
問題だったのはinputに入力された値e.target.valueをsetStateに渡して、すぐにエラーチェック関数validateFormを実行していた事でした。stateの更新は即座に行われると思っていたのでこの書き方をしましたが、stateの更新は即座には行われるのではなく、レンダリングのタイミングで更新されるのでバリデーションチェックが常にfalseとなりエラー文が消えない現象が起きていました。
そのため以下のコードを書いて解決しました。
// 学習内容を管理するステート
const [contents, setContents] = useState("");
// 学習時間を管理するステート
const [time, setTime] = useState(0);
// エラーを管理するステート
const [hasError, setHasError] = useState(true);
// onChangeイベントハンドラ:入力された学習内容を取得する
const handleContentsChange = (e) => {
const value = e.target.value // 追加
setContents(value); // 変更
validateForm(value, time); // 変更:引数にフォームに入力された値を渡す
};
// onChangeイベントハンドラ:入力された学習時間を取得する
const handleTimeChange = (e) => {
const value = Number(e.target.value); // 追加
setTime(value); // 変更
validateForm(value, contents); // 変更:引数にフォームに入力された値を渡す
};
// 入力エリアをチェックする関数
const validateForm = (contents, time) => { // 変更:引数を追加
if (contents === "" || time === 0 || time === "") {
setHasError(true);
} else {
setHasError(false);
}
};
// 学習内容入力エリア
<input
type="text"
value={contents}
onChange={handleContentsChange}
/>
// 学習時間入力エリア
<input
type="num"
min="0"
value={time}
onChange={handleTimeChange}
/>
変更点としては、エラーチェック関数validateFormの引数に学習内容or学習時間のフォームに入力された値を直接渡す形に変えました。こうすることで、stateの更新に依存せず、渡された値で正常に条件分岐することが出来るようになりました。
他にも、使わなくても良いところでuseStateを使い処理を煩雑にしてしまったり、論理積と論理和を正しく理解していなかったせいで条件式の書き方で謎に沼ったり、reduceの挙動をよく分かっていなかったせいで合計時間の算出に苦戦したりと躓きの連続でしたがChatGPTの力を借りつつ何とか完成出来ました。
気づき
今回のアプリ開発を通してReact以前にJSの理解が弱いのを痛感したので躓いたところを全て洗い出して復習します。また、自分が圧倒的にアウトプット不足だということにも気づきました。
今はプログラミングの教材がたくさんあるので勉強するには困らない時代ですが、インプットするだけだと知識としてはまだまだ弱いです。ハンズオン形式の教材や実際にアプリを作るフェーズが用意されている教材もありますが、教材で得た知識の範囲にプラスアルファした内容のアウトプットしないと本当の意味で知識を定着させるのは難しいと思います。
最後に
今回のアプリ開発を通して自分が知らなかったor分かっているつもりだったところを知れて勉強になったのはもちろん、自分の現在の実力やこれからの学習の仕方についてなどたくさんの気づきがあってとても良い経験となりました。
インプットだけはダメ。ゼッタイ。必ずアウトプットもする。
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼


