506文字
3分
編集

Q. 削除された変数への参照が、グローバル変数と一致しているためエラーが出ない

#状況

まず event という名前の引数を受け取る次のようなコンポーネントがあった。

tsx
const SomeComponent = ({ event }) => {
  return (
    <div>
      <Button
        onClick={() => {
          // eventを利用した処理
        }}
      >
        Click me
      </Button>
      {/* とても長いコード */}
    </div>
  );
};

次に click event を利用したくなり、次のように引数から受け取る event を rename した。

tsx
const SomeComponent = ({ someEvent }) => {
  return (
    <div>
      <Button
        onClick={(event) => {
          // someEventとeventを利用した処理
        }}
      >
        Click me
      </Button>
      {/* とても長いコード */}
    </div>
  );
};

このとき、変更箇所自体は想定通りの挙動をしていたが、それ以降のコードで event という変数を利用している箇所が残っていた。

通常の変数であれば、このような参照があるとエラーが出るが、グローバル変数である event と重複していたためエラーが検出されなかった。

#対応策

このような問題を防ぐために、ESLint の no-restricted-globals ルールを利用することができる。

https://eslint.org/docs/latest/rules/no-restricted-globals

js
{
  rules: {
    "no-restricted-globals": ["error", "event"]
  }
}

このルールで指定されたグローバル変数を利用する場合、明示的にglobalThis.eventのように指定しなければエラーが出るようになるため、意図しないグローバル変数への参照を防ぐことができる。

#余談

no-restricted-globalsルールでeventという変数名は名指しで言及されている。

For instance, early Internet Explorer versions exposed the current DOM event as a global variable event, but using this variable has been considered as a bad practice for a long time. Restricting this will make sure this variable isn’t used in browser code. - https://eslint.org/docs/latest/rules/no-restricted-globals

このように歴史的な経緯などにより、ブラウザ環境には非常に多くのグローバル変数が存在し、中にはeventのように変数名が被ってしまいそうなものが複数存在する。

ESLint で利用するglobalsパッケージのbrowserフィールドを見ると、event以外にもerrorlengthnamestatustopなどが存在している。

https://github.com/sindresorhus/globals/blob/v15.11.0/globals.json#L29

編集