変数と const

Part 0 · React の前に

変数と const

なぜ React では let をほとんど使わないのか

React のコードを開くと、いちばん最初に目に入るのが const です。ほとんどの行がこれで始まっていると言ってもいいくらいです。

const は「変わらない値」だと説明されることが多いのですが、 それだけだとあとで必ずつまずきます。 const で作ったはずのデータが、いつのまにか書き換わっているからです。

この章では、const が実際には何を守っているのかをはっきりさせます。

変数は、値につけた名前

プログラムでは、あとで使いたい値に名前をつけておきます。これが変数です。

const name = "さとう";

console.log(name); // "さとう"

これで「name と書いたら "さとう" のこと」という約束ができました。 名前をつけておくと、同じ値を何度も書かずに済みますし、 その値が何を表しているのかが読む人に伝わります。

const-object.ts

// const で作ったオブジェクト
export const user = { name: "さとう", age: 20 };

// user そのものを入れ替えることはできない。これを書くとエラーになる
// user = { name: "すずき", age: 30 };

// でも、中身を書き換えることはできてしまう
user.name = "すずき";
user.age = 30;

const と let

変数を作る方法は、いまは 2 つだけ覚えれば十分です。

const name = "さとう";
name = "すずき"; // エラー。あとから入れ直せない

let count = 0;
count = 1; // これは通る
  • const … あとから別の値を入れ直せない
  • let … 入れ直せる

var という古い書き方もありますが、 いま新しく書くコードでは使いません。見かけたら「古いコードだ」と思って大丈夫です。

React ではほとんど const

React のコードを見ると、変数がほぼ全部 const です。 これは行儀の問題ではなく、React の考え方がそうなっているからです。

React では、値を書き換えて画面を変える、ということをしません。新しい値を作って React に渡すと、React が画面を描き直します。 書き換えないので、入れ直せる必要がないのです。

const-object.ts

// const で作ったオブジェクト
export const user = { name: "さとう", age: 20 };

// user そのものを入れ替えることはできない。これを書くとエラーになる
// user = { name: "すずき", age: 30 };

// でも、中身を書き換えることはできてしまう
user.name = "すずき";
user.age = 30;

const が守るのは「名札」だけ

ここが、この章でいちばん大事なところです。

const は「値を変えられなくするもの」ではありません。「その名前に、別の値を入れ直せなくするもの」です。 名前と値の結びつきを固定しているだけで、値そのものには手を出していません。

const user名札{ name: "さとう" }名札を別の箱に付け替えるuser = { name: "すずき" }箱の中の値を書き換えるuser.name = "すずき"
const が固定するのは名札の付け先だけ。箱の中身には関与しない

文字列や数値のような単純な値なら、この違いは表に出てきません。 「入れ直せない」=「変えられない」と考えても、結果は同じだからです。

問題はオブジェクトと配列です。これらは中身を持っています。 そして中身の書き換えは、名札の付け替えではありません。

const のオブジェクト

入れ替えていないので、const でも止められない

const で作ったのに、中身が書き換わっています

{ name: "すずき", age: 30 }

user = ... なら「名札の付け替え」なのでエラーになりますが、user.name = ... は「箱の中身の書き換え」なので通ってしまいます。

const-object.ts

// const で作ったオブジェクト
export const user = { name: "さとう", age: 20 };

// user そのものを入れ替えることはできない。これを書くとエラーになる
// user = { name: "すずき", age: 30 };

// でも、中身を書き換えることはできてしまう
user.name = "すずき";
user.age = 30;

配列も同じ

配列も中身を持っているので、同じことが起きます。push は「配列を入れ替える」操作ではなく 「配列の中に足す」操作なので、const でも通ります。

const の配列

要素が 3 つに増えている

push したぶんだけ要素が増えている

["さとう", "すずき", "たかはし"]

const-array.ts

// 配列も同じ。const で作っても中身は増やせる
export const members = ["さとう", "すずき"];

// push は「配列を入れ替える」のではなく「配列の中に足す」操作
members.push("たかはし");

理解できたか確かめる

確認クイズ

const で作った変数について、正しいのはどれ?

確認クイズ

次のうち、エラーになるのはどれ?

const-object.ts

// const で作ったオブジェクト
export const user = { name: "さとう", age: 20 };

// user そのものを入れ替えることはできない。これを書くとエラーになる
// user = { name: "すずき", age: 30 };

// でも、中身を書き換えることはできてしまう
user.name = "すずき";
user.age = 30;

この章のまとめ

  • 変数は、値につけた名前
  • const名前と値の結びつきを固定する
  • 固定されるのは名札だけで、オブジェクトや配列の中身は書き換えられてしまう
  • React では基本的に const を使い、let はほとんど出てこない

const-object.ts

// const で作ったオブジェクト
export const user = { name: "さとう", age: 20 };

// user そのものを入れ替えることはできない。これを書くとエラーになる
// user = { name: "すずき", age: 30 };

// でも、中身を書き換えることはできてしまう
user.name = "すずき";
user.age = 30;