JavaScriptでアプリを作り始めると、最初は「動けばOK」でコードを書いてしまいがちです。
ボタンのクリック処理、配列の操作、DOMの更新をすべて1つの関数にまとめて書いていませんか。
私自身も、ToDoリストを作り始めた頃は、クリックイベントの中にロジックとUI更新を詰め込み、あとから修正しようとして自分のコードが読めなくなる、という状況を何度も経験しました。
結論から言うと、UI(画面)とロジック(処理)を分けて考えるだけで、コードは一気に読みやすく、壊れにくくなります。
この記事では、JavaScript初心者でも実践できる「UIとロジックを分解する考え方」と具体的なコード構成について解説します。
なぜUIとロジックを分ける必要があるのか
UIとロジックを分ける最大の理由は、「変更に強いコード」を作るためです。
たとえば、次のような変更が入ることはよくあります。
・表示方法を少し変えたい
・ボタンを追加したい
・データの扱い方だけ変えたい
UIとロジックが混ざったコードでは、どこを直せばいいのか判断が難しくなります。一方で役割が分かれていれば、画面の問題なのか、処理の問題なのかを切り分けて修正できるようになります。
これはReactやVueなどのフレームワークを学ぶ前段階としても、とても重要な考え方です。
UIとロジックが混ざっているコードの例
まずは、ありがちな例を見てみます。
button.addEventListener("click", () => {
const input = document.getElementById("task");
const value = input.value;
tasks.push(value);
list.innerHTML = "";
tasks.forEach(task => {
const li = document.createElement("li");
li.textContent = task;
list.appendChild(li);
});
input.value = "";
});
このコードでは、次の処理がすべて一箇所に書かれています。
・ユーザー操作の受け取り
・配列の更新
・DOMの再描画
・入力欄のリセット
動作はしますが、後から見返すと「何をしているコードなのか」が分かりにくくなりがちです。
UIとロジックを分解する基本的な考え方
分解する際の考え方はシンプルです。
- ロジック:データをどう扱うか(配列操作・条件分岐)
- UI:画面をどう表示するか(DOM操作)
この2つを意識して、役割ごとに関数を分けていきます。
ロジックは「データだけ」を扱う
まずはロジック側です。
ロジックの関数では、DOMには一切触れないようにします。
let tasks = [];
function addTask(text) {
tasks.push(text);
}
function getTasks() {
return tasks;
}
ここでは、配列の操作だけを行っています。
画面に表示するかどうかは一切考えません。
UIは「表示」だけを担当する
次にUI側です。
UIの関数では、受け取ったデータを画面に反映することだけに集中します。
function renderTasks(taskList) {
list.innerHTML = "";
taskList.forEach(task => {
const li = document.createElement("li");
li.textContent = task;
list.appendChild(li);
});
}
この関数は、「タスクをどう表示するか」しか知らない構造になっています。
イベントは「つなぎ役」として使う
イベントリスナーの役割は、UI操作とロジックをつなぐことです。
button.addEventListener("click", () => {
const value = input.value;
addTask(value);
renderTasks(getTasks());
input.value = "";
});
ここでは処理の流れが非常に読みやすくなっています。
- 入力値を取得
- ロジックでタスク追加
- UIを再描画
- 入力欄をリセット
この構造が、UIとロジック分離の基本形です。
再レンダリングと相性が良い理由
UIとロジックを分けていると、「再レンダリング」の実装が楽になります。
一度DOMを全削除して、配列の状態を元に描画し直す。
この考え方は、後にReactのstateやrenderの考え方にも直結します。
「画面は、常にデータの結果である」
この発想を持てるようになると、コード設計が一段レベルアップします。
TypeScriptへの拡張もしやすい
この分離設計は、TypeScriptとの相性も抜群です。
type Task = {
id: number;
text: string;
};
ロジック側に型を定義し、UIはその型を受け取って表示する。
責務が分かれているからこそ、型の恩恵を最大限に受けられます。
まとめ
JavaScriptでUIとロジックを分解することは、単なる「きれいな書き方」ではありません。
保守性・拡張性・学習効率を一気に高める設計の考え方です。
最初から完璧に分ける必要はありません。
「これは画面の仕事か?処理の仕事か?」と一度考えるクセをつけるだけで、コードは確実に変わっていきます。
この考え方を身につければ、ReactやVueに進んだときもスムーズに理解できるはずです。

コメント