1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React(JS)で学習記録アプリを作成してみた

Last updated at Posted at 2026-01-11

はじめに

Reactの学習のマイルストーンとして簡単な学習記録アプリを作成しました。
動きとしては学習内容と学習時間を入力して登録すると
学習内容が登録されていき、累計の学習時間が表示されるというものです。
output2.gif

ReactのuseStateやmap, reduceなどを学ぶ上でちょうど良いテーマになっています。

実際に作る中で、苦労したこと、いくつか疑問に思った点やハマった点を注意点として以下にまとめました。

useStateを使う時のNullの取り扱い

nullというのは何も無い事を明示的に表す時に使うと思います。
意図を伝える上では便利ですが、useStateにおいて、安易にnullを使うのは危険だと思いました。

Code Snippetともに確認してみましょう。
以下はCodeSandboxのApp.jsに直接貼り付けて検証いただけます。

App.js
import { useState } from "react";

export default function App() {
  const [value, setValue] = useState(null);

  return (
    <div style={{ padding: 20 }}>
      <input
        type="number"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <div style={{ marginTop: 10 }}>
        <button onClick={() => setValue(null)}>null でリセット</button>
        <button onClick={() => setValue("")}>空文字でリセット</button>
      </div>
      <p>state: {value === null ? "null" : `"${value}"`}</p>
    </div>
  );
}

このコードはuseStateのvalueをnullでリセットするか空文字でリセットするかを選べるようなUIになっています。どちらで初期化しても結果には大差ないのではないかと思うかもしれませんが、実際には異なります。nullでsetした場合はstateにはnullが入るのに、input側にはnullで初期化されず、値が残ってしまいます。つまり、setするときはnullを使わず、""のような空文字列などデータ型に応じたsetを行った方が良いです。

スクリーンショット 2026-01-11 22.21.43.png

input type="number”の取り扱い

例えば、勉強時間の入力値などを数値を受け取る際に、inputを使い、type="number"を指定すると思います。
type="number"を指定したからと言って、入力された値が数値型に変換されていると期待してはいけません。実際には文字列型になっています。したがって、数値型が返ってきていると思い込んで、その後の処理をするとハマってしまいます。

こちらもCode Snippetともに確認してみましょう。

App.js
import { useState } from "react";

export default function App() {
  const [value, setValue] = useState("");

  const handleChange = (event) => {
    const inputValue = event.target.value;
    console.log("値:", inputValue);
    console.log("型:", typeof inputValue);
    setValue(inputValue);
  };

  return (
    <div>
      <label>数値を入力: </label>
      <input type="number" value={value} onChange={handleChange} />
      <p>入力値: {value}</p>
      <p>: {typeof value}</p>
    </div>
  );
}

結果は以下の通りです。
スクリーンショット 2026-01-11 21.44.30.png

componentsの名前の付け方

これは初めてReactでcomponentsの分割をするときに悩ましい問題だと思いました。
今回は次のように分けてみました。

ui.png

例えば、登録内容に不備がある場合のcomponentsとしてRecordsValidator.jsxを作成しましたが、Validatorとはデータなどを検証するツール的な意味合いがあるのでcomponentにするならもう少し他の名前が適切かもしれないなと思います。

Number vs parseInt

NumberとparseIntはどちらも数値型に変換するための関数ですが、挙動が少し異なります。
例えば、入力として123abc->123を是とするのか、考えた上で選択した方が良さそうです。

App.js
import { useState } from "react";

export default function App() {
  const [value, setValue] = useState("");

  const handleChange = (event) => {
    const inputValue = event.target.value;
    console.log("値:", inputValue);
    console.log("型:", typeof inputValue);
    setValue(inputValue);
  };

  return (
    <div>
      <label>数値を入力: </label>
      <input type="number" value={value} onChange={handleChange} />
      <p>入力値: {value}</p>
      <p>: {typeof value}</p>
    </div>
  );
}

スクリーンショット 2026-01-11 22.50.04.png

以上、雑多な内容ですが、Tipsになります。

成長したと感じる点

ベタではありますが、知っているとできるは異なります。
簡単なアプリケーションではありますが、useState, map, reduceなどの基本的な文法の使い方やコンポーネントへの分割、実装過程で出てくるバグ取りをスクラッチからやることでReact上でのアプリ開発の一連のプロセスを体験でき,実際に使える知識が身についたと思います。

JISOUのメンバー募集中!

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?