PC-LABOを試すためのJavaScript・React入門(第2回)~配列・オブジェクト・map/filter・import/export・JSON・Date~【GitHub対応】

JavaScript / React

はじめに

第1回では、変数・型・条件分岐・ループ・関数といった、JavaScriptの最も基本的な文法を扱った。

第2回では、Reactのコードに頻繁に登場するJavaScriptの書き方を扱う。
「Reactで学ぶ 予定管理アプリ開発」でつまずきやすい部分の多くは、Reactそのものではなく、ここで扱う書き方である。これに慣れておけば、本編がぐっと読みやすくなる。

今回やること

  • 配列とオブジェクトを使う
  • 分割代入とスプレッド構文を使う
  • map・filter・findで配列を扱う
  • importとexportでファイルを分ける
  • JSONで、データと文字列を相互に変換する
  • Dateで、カレンダーに必要な日付を求める

実行環境

第1回と同じく、GitHub Codespacesのターミナルで、Node.jsを使って実行する。

ソースコードは、次の筆者のリポジトリの02_javascript-for-reactフォルダにある。

GitHub – HappyTalk10/pc-labo-js-react-intro
Contribute to HappyTalk10/pc-labo-js-react-intro development by creating an account on GitHub.

配列

配列は、複数の値を順番に並べてまとめたものである。角括弧[]で書く。

const titles = ["会議", "歯医者", "飲み会"];

console.log(titles[0]); // 会議(番号は0から始まる)
console.log(titles.length); // 3

titles.push("ランチ"); // 末尾に追加(元の配列を書き換える)
console.log(titles); // [ '会議', '歯医者', '飲み会', 'ランチ' ]

pushは便利だが、元の配列を書き換えてしまう。Reactでは、この書き換え方を基本的に使わない。代わりの方法を、後ほどスプレッド構文のところで紹介する。

オブジェクト

オブジェクトは、名前(キー)と値のペアをまとめたものである。波括弧{}で書く。

const plan = { id: 1, date: "2026-10-01", title: "歯医者", done: false };

console.log(plan.title); // 歯医者
console.log(plan["date"]); // 2026-10-01

plan.done = true; // const でも、オブジェクトの中身は書き換えられる
console.log(plan); // { id: 1, date: '2026-10-01', title: '歯医者', done: true }

constで宣言していても、オブジェクトの中身は書き換えられる。constが禁止するのは、変数自体への再代入である。

配列の中にオブジェクト

予定管理アプリでは、「予定のオブジェクト」を並べた配列でデータを持つ。この形が、このシリーズで最もよく使う形になる。

const plans = [
  { id: 1, date: "2026-10-01", title: "歯医者", done: false },
  { id: 2, date: "2026-10-02", title: "会議", done: false },
  { id: 3, date: "2026-10-03", title: "飲み会", done: false },
];

console.log(plans[1].title); // 会議
console.log(plans.length); // 3

分割代入

オブジェクトや配列から、必要な値を取り出して変数にする書き方である。

const plan = { id: 1, date: "2026-10-01", title: "歯医者", done: false };

const { date, title } = plan;
console.log(date, title); // 2026-10-01 歯医者

const colors = ["赤", "青", "緑"];
const [first, second] = colors;
console.log(first, second); // 赤 青

オブジェクトは{}でキーの名前を指定し、配列は[]で順番に取り出す。

関数の引数でも使える。Reactでは、コンポーネントが受け取る値(props)をこの形で書くことが多い。

const formatPlan = ({ date, title }) => `${date} ${title}`;
console.log(formatPlan(plan)); // 2026-10-01 歯医者

スプレッド構文

...(ドット3つ)で、配列やオブジェクトの中身を展開する書き方である。元のデータを書き換えずに、新しいデータを作る時に使う。

// オブジェクトのコピー + 一部だけ変更
const updated = { ...plan, done: true };
console.log(updated); // { id: 1, date: '2026-10-01', title: '歯医者', done: true }
console.log(plan.done, updated.done); // false true(元は変わらない)

// 配列のコピー + 要素の追加
const newPlans = [...plans, { id: 4, date: "2026-10-04", title: "ランチ", done: false }];
console.log(plans.length, newPlans.length); // 3 4(元は変わらない)

pushのように元の配列を書き換えるのではなく、「新しい配列を作る」のがポイントである。Reactは、新しい値に変わったことを手がかりに画面を更新する。そのため、Reactの状態を更新する時は、この書き方が基本になる。詳しくは第3回で扱う。

map・filter・find

配列を扱う代表的なメソッドを3つ紹介する。どれも、元の配列は書き換えない。

const plans = [
  { id: 1, date: "2026-10-01", title: "歯医者", done: false },
  { id: 2, date: "2026-10-02", title: "会議", done: true },
  { id: 3, date: "2026-10-03", title: "飲み会", done: false },
];

map:すべての要素を変換する

const titles = plans.map((plan) => plan.title);
console.log(titles); // [ '歯医者', '会議', '飲み会' ]

const labels = plans.map((plan) => `${plan.date} ${plan.title}`);
console.log(labels);
// [ '2026-10-01 歯医者', '2026-10-02 会議', '2026-10-03 飲み会' ]

mapは、配列の要素を1つずつ関数に渡し、その結果を集めた新しい配列を返す。Reactでは、予定の一覧を画面に並べる時に使う。

filter:条件に合う要素だけを集める

const notDone = plans.filter((plan) => !plan.done);
console.log(notDone.map((plan) => plan.title)); // [ '歯医者', '飲み会' ]

!plan.doneは、「doneがfalse」という意味である。

find:条件に合う最初の1件を取り出す

const found = plans.find((plan) => plan.id === 2);
console.log(found); // { id: 2, date: '2026-10-02', title: '会議', done: true }

Reactの状態更新でよく使う形

filter、map、スプレッド構文を組み合わせると、削除や更新を「元を書き換えずに」書ける。予定管理アプリで何度も出てくる形である。

// 削除:id が 2 以外のものを残す
const removed = plans.filter((plan) => plan.id !== 2);
console.log(removed.map((plan) => plan.id)); // [ 1, 3 ]

// 更新:id が 1 のものだけ done を反転し、他はそのまま
const toggled = plans.map((plan) =>
  plan.id === 1 ? { ...plan, done: !plan.done } : plan
);
console.log(toggled.map((plan) => `${plan.id}:${plan.done}`));
// [ '1:true', '2:true', '3:false' ]

console.log(plans[0].done); // false(元の配列は変わっていない)

更新のコードにある条件 ? A : Bは、三項演算子である。「条件が真ならA、偽ならB」という意味になる。

import と export

プログラムが大きくなると、ファイルを分けたくなる。他のファイルの関数や値を使うには、exportで公開し、importで読み込む。

まず、公開する側のファイル(plan-utils.mjs)である。

// 名前付きエクスポート(複数書ける)
export const appName = "予定管理アプリ";
export const formatPlan = (plan) => `${plan.date} ${plan.title}`;

// デフォルトエクスポート(1ファイルに1つだけ)
export default function countNotDone(plans) {
  return plans.filter((plan) => !plan.done).length;
}

次に、読み込む側のファイル(main.mjs)である。

// デフォルトは波括弧なし、名前付きは波括弧あり
import countNotDone, { appName, formatPlan } from "./plan-utils.mjs";

const plans = [
  { id: 1, date: "2026-10-01", title: "歯医者", done: false },
  { id: 2, date: "2026-10-02", title: "会議", done: true },
  { id: 3, date: "2026-10-03", title: "飲み会", done: false },
];

console.log(appName); // 予定管理アプリ
console.log(formatPlan(plans[0])); // 2026-10-01 歯医者
console.log(countNotDone(plans)); // 2

実行は、04_modulesフォルダの中で行う。

node main.mjs

ファイルの拡張子が.mjsなのは、Node.jsにこのファイルでimportを使うと伝えるためである。ReactのプロジェクトではViteが処理してくれるので、.jsや.jsxのファイルでそのままimportを書ける。

JSON

JSONは、データを文字列として表現する形式である。
ブラウザに予定を保存する時に、配列やオブジェクトを文字列に変換する必要があるため、配列やオブジェクトをlocalStorageに保存するときに使う。

const plans = [
  { id: 1, date: "2026-10-01", title: "歯医者", done: false },
  { id: 2, date: "2026-10-02", title: "会議", done: true },
];

// オブジェクト・配列 → 文字列
const text = JSON.stringify(plans);
console.log(text);
// [{"id":1,"date":"2026-10-01","title":"歯医者","done":false},{"id":2,"date":"2026-10-02","title":"会議","done":true}]
console.log(typeof text); // string

// 文字列 → オブジェクト・配列
const restored = JSON.parse(text);
console.log(restored[0].title); // 歯医者
console.log(restored.length); // 2

localStorage

localStorageは、ブラウザに文字列を保存しておく機能である。ブラウザを閉じても、データが残る。文字列しか保存できないので、先ほどのJSONと組み合わせて使う。

localStorage.setItem("plans", JSON.stringify(plans)); // 保存
const saved = localStorage.getItem("plans"); // 取り出す(無ければ null)
const loaded = saved ? JSON.parse(saved) : []; // 文字列を配列に戻す

localStorageはブラウザの機能なので、Node.jsでは使えない。
試したい場合は、ブラウザの開発者ツール(F12キー)の「コンソール」に貼り付けて動かす。
本編では、予定管理アプリに実際に組み込む。

Date

カレンダーを作るには、日付の計算が必要になる。Dateの基本的な使い方を押さえておこう。

// 月は0始まり(0 = 1月, 9 = 10月)
const d = new Date(2026, 9, 1);
console.log(d.getFullYear(), d.getMonth() + 1, d.getDate()); // 2026 10 1

// 曜日(0 = 日曜 〜 6 = 土曜)
const weekdays = ["日", "月", "火", "水", "木", "金", "土"];
console.log(d.getDay(), weekdays[d.getDay()]); // 4 木

月が0始まりなのが、最大のつまずきポイントである。10月は9で指定し、取り出す時は+ 1して表示する。

カレンダーに必要な値は、次のように求められる。

// その月の日数:「翌月の0日」は「当月の末日」になる
const lastDay = new Date(2026, 10, 0).getDate();
console.log(lastDay); // 31

// 月初の曜日は、カレンダーの最初に必要な空白マスの数になる
const blankCells = new Date(2026, 9, 1).getDay();
console.log(blankCells); // 4

日付を"2026-10-01"の形式の文字列にするには、数字を2桁に揃える必要がある。

const pad = (n) => String(n).padStart(2, "0");
const text = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
console.log(text); // 2026-10-01

padStart(2, "0")は、2桁に満たない場合に、左側を0で埋めるメソッドである。

今回のまとめ

  • 予定のデータは、「オブジェクトを並べた配列」で持つ
  • 分割代入で、オブジェクトや配列から値を取り出せる
  • スプレッド構文(...)で、元を書き換えずに新しいデータを作れる
  • mapは変換、filterは絞り込み、findは1件の取り出しに使う
  • 削除はfilter、更新はmapとスプレッド構文を組み合わせる
  • exportで公開し、importで読み込む
  • JSON.stringifyとJSON.parseで、データと文字列を変換する。localStorageへの保存に使う
  • Dateの月は0始まりである

次回予告

第3回では、いよいよReactの入門に入る。JSX、コンポーネント、props、useStateの考え方を、小さなコードで体験する。今回のスプレッド構文やmapが、そのまま登場する。

タイトルとURLをコピーしました