React の useReducer を使うとき action ごとの処理を分けるのに switch 文を使うことが多いですが、複数の case 内で同じ名前の変数を使いたい時 const
で定義するとハマってしまうことがあります。
case 内で同じ名前の変数を const で定義するとエラーになる
例えば次のような reducer を作った時、 case 'DELETE'
内で id は既に定義済みというエラーが発生します。
const reducer = (state, action) => { switch(action.type) { case 'CREATE': const { id, title } = action; return [...state, {id, title}]; case 'DELETE': const { id } = action; return state.filter((item) => item.id !== id); default: return false; } };
=> Parsing error: Identifier 'id' has already been declared
😇
switch 文の case 節はスコープを作らない
理由はシンプルで case
節はブロックではないのでスコープを作らないからです。
this is due to both
let
statements being interpreted as duplicate declarations of the same variable name within the same block scope.
cf. switch - JavaScript | MDN
switch 文内で変数定義を const でするなら case 節を {}
で囲えばOK
const reducer = (state, action) => { switch(action.type) { case 'CREATE': { const { id, title } = action; return [...state, {id, title}]; } case 'DELETE': { const { id } = action; return state.filter((item) => item.id !== id); } default: return false; } };
こうすると、case 節内がそれぞれ別のスコープになるので、同じ変数名を const
で定義できるようになる。✌️₍ ᐢ. ̫ .ᐢ ₎✌️ ヤッタネ.
block statement と呼ぶらしい cf. block - JavaScript | MDN
まとめ
文 ( statement ) はスコープを作る。
節 ( clause ) はスコープを作らない。
みたいな認識で良いのかな?
[参考]

Nintendo Switch あつまれ どうぶつの森セット
- 発売日: 2020/03/20
- メディア: Video Game