学習記録アプリを作成しました!
プログラミングスクールJISOUに参加して、最初の課題で作成したのは「学習記録アプリ」です!
このアプリは、学習内容と学習時間を入力し、「登録」ボタンを押すと、その記録が一覧で表示されるというシンプルなものです。
完成したアプリ
実際に作成したアプリとそのコードです。
ReactとTypeScriptを使いました。
import { useState } from "react";
function App() {
const [records, setRecords] = useState<any[]>([]);
const [studyText, setStudyText] = useState<string>("");
const [studyTime, setStudyTime] = useState<number>(0);
const [error, setError] = useState<string>("");
const handleChangeText = (e: React.ChangeEvent<HTMLInputElement>) => {
setStudyText(e.target.value);
};
const handleChangeTime = (e: React.ChangeEvent<HTMLInputElement>) => {
setStudyTime(Number(e.target.value));
};
const onSubmit = () => {
const newStudy = {
id:Date.now(),
studyText:studyText,
studyTime:studyTime
}
const newRecord = [...records,newStudy]
setRecords(newRecord);
setStudyText("");
setStudyTime(0);
const error = () => {
if(studyText === "" || studyTime === 0) {
setError("入力されていない項目があります");
setRecords([]);
return
} else if (studyText !== "" && studyTime > 0) {
setError("");
return
}
}
error();
};
const totalStudyTime = records.reduce((total, record) => {
return total + parseInt(record.studyTime)}, 0);
return (
<>
<div>
<h1>学習記録一覧</h1>
<div>
<div>学習内容<input type="text" value={studyText} onChange= {handleChangeText}/></div>
<div>学習時間<input type="number" value={studyTime} onChange= {handleChangeTime}/>時間</div>
<div>入力されている学習内容:{studyText}</div>
<div>入力されている時間:{studyTime}時間</div>
{records.map((record) => {
return(
<div key={record.id}>{record.studyText}{record.studyTime}時間</div>
)
})}
<button onClick={() => onSubmit()}>登録</button>
<div>合計時間:{totalStudyTime}/1000(h)</div>
<div>{error}</div>
</div>
</div>
</>
)
}
export default App;
記録の表示が崩れた
「登録」ボタンを押した時、入力した内容が意図通りに表示されませんでした。
本来は、以下の赤枠のように学習内容「test」と学習時間「2」を入力して登録すると、画面には「test2時間」と表示されます。
しかし、その時に表示された画面表示は「test」と「1」が別々の行に分かれて表示されてしまいました。
問題のコード
原因
原因は、記録を管理していた配列(records)にデータを追加する方法にありました。
記録用の配列に"test"と"2"が別々に追加されていたことが原因です。
const onSubmit () = {
// これだと配列に2つのデータが追加されてしまう
const newRecord = {...records, studyText, studyTime}
setRecords(newRecord);
}
このコードでは、records配列にstudyText(文字列)とstudyTime(数値)がそれぞれ別々の要素として追加していました。
表示処理が、配列のそれぞれのデータを改行してしまうため、2行で表示されていました。
解決策
"test"と"2"を{ }に囲んで1つのオブジェクトにしてから配列に追加しました。
const onSubmit = () => {
const newStudy = {
id:Date.now(),
studyText:studyText,
studyTime:studyTime
}
const newRecord = [...records,newStudy]
setRecords(newRecord);
setStudyText("");
setStudyTime(0);
}
これによって、1つの記録が1行で表示されるようになりました。
学習記録アプリの作成を振り返って
このアプリを作成するにあたって、正直いいますと、数日もかかってしまいました。
今までAIにすごく頼っていたため、自分で考えて実装をすることができず、とてもシンプルなアプリでも1つ1つの実装にとても苦戦しました。
ですが、この状況を打破したいと思い、わからないところは記事を見て調べたり、持っている参考書で解決しようと思い進めました。
改めて書いたコードを見直して自分自身でも思いましたが、もっとコードを簡潔にできるんだろうな、この型は絶対にエラーの大きな原因になるだろうな、とツッコミどころ満載な部分はたくさんあるかと思います。
まずは自分で考えて動かすことからが大事だなと思ったので、コードの綺麗さは全く意識してませんでした。
これからたくさん手を動かして、そこは磨いていこうと思います。