2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[clean code]分割代入は積極的に使おう

Posted at

はじめに

FrontEndの開発でTypeScriptを使っている方は多いと思います。
チームで開発を行うようになってくると、可読性の高い記述方法ってなんだろう?と考えることが増えるのではないでしょうか?

今回、可読性を高めるために分割代入を積極的に使ってみるのはどうか?というのを簡単なコード例を交えて紹介します。

基礎編

まずは、Listのケースを見てみます。
分割代入をせずに記述した場合を見てみます。

const coordinate = [42, 79, 68];
console.log(coordinate[0]);
console.log(coordinate[1]);
console.log(coordinate[2]);

console.log()の中身がscores[0]のような記述となっていて、
なんの値を表示しているのか不明確になります。

これを分割代入を使って表現すると以下のようになります。

const coordinate = [42, 79, 68];
const [x, y, z] = coordinate;
console.log(x);
console.log(y);
console.log(z);

分割代入を行うことで1行増えましたが、
console.log()の中身に何を入れているのか直感的に読めばわかるようになります。

この例ではシンプルすぎて嬉しさがよくわからないかもしれないので少し複雑な例を記述してみます。

const today = '1958/11/22';
const splitData = today.split('/');
console.log(`${splitData[0]}${splitData[1]}${splitData[2]}日`);

console.log(`${splitData[0]}年${splitData[1]}月${splitData[2]}日`)
が非常に読みにくいのではないでしょうか?

これを分割代入にすると、

const today = '1958/11/22';
const [year, month, day] = today.split('/');
console.log(`${year}${month}${day}日`);

このように記述することができ、
console.log(`${year}年${month}月${day}日`)の部分がそのまま読めば、
どんな値が表示されるかが一目瞭然となります。

日々、開発を行うにあたり急ぎ実装をしようとすると、
つい、
console.log(`${splitData[0]}年${splitData[1]}月${splitData[2]}日`)
このような記述が出てきてしまうような書き方になってしまうのではないでしょうか?

Reactの開発ではどう活かせるのか?

ここまで記述したものは配列の分割代入でしたが、オブジェクトでも分割代入を行うことができます。
調べるとたくさんのユースケースが出てくると思いますので、この記事は差別化の意味も込めて、ニッチな例を示したいと思います。

TDDを用いて開発を行っているとtest内で、

it('hoge-test', () => {
  render(<HogeComponent />;

  const input = screen.getByRole('textbox');
  const addButton = screen.getByRole('button', { name: '追加' };
  const closeButton = screen.getByRole('button', { name: '閉じる' };
  const cancelButton = screen.getByRole('button', { name: 'キャンセル' };
  const saveButton = screen.getByRole('button', { name: '保存' };

  // ... アクション、アサーション略
})

といった、各要素を変数においてuserEvent.type(), userEvent.click()などを行ったりすると思います。
当然、テストは一個ではないので、何回も同じ要素を変数に置き…というのは、DRYの観点からも望ましくないと思います。

この時、使い回しの処理は関数化するのですが、この時も分割代入を使うと賢くテストを記述することができます。
まずは、関数化すると以下のようになります。

const renderHogeComponent = () => {
  render(<HogeComponent />;

  const inputBox = screen.getByRole('textbox');
  const addButton = screen.getByRole('button', { name: '追加' };
  const closeButton = screen.getByRole('button', { name: '閉じる' };
  const cancelButton = screen.getByRole('button', { name: 'キャンセル' };
  const saveButton = screen.getByRole('button', { name: '保存' };

  return { inputBox, addButton, closeButton, cancelButton, saveButton };
}

このようにして、返り値をオブジェクトで記述しておきます。
この状態で分割代入を使いながらテストを記述すると、

it('閉じるボタンをクリックした時、~~', async () => {
  const { closeButton } = renderHogeComponent();

  await userEvent.click(closeButton);

  // ...アサーション略
});

it('インプットボックスにテキストを入力し、追加ボタンを押すと~~', async () => {
  const { inputBox, addButton } = renderHogeComponent();
  const inputText = "My name is Hoge";

  await userEvent.type(inputText);
  await userEvent.click(addButton);

  // ...アサーション略
});

といったように、actassertionに使いたい要素だけを変数化して取得でき、テスト内で使用できます。

もし、分割代入を使わないと、2個目のテストはこんな感じになってしまいます。

it('インプットボックスにテキストを入力し、追加ボタンを押すと~~', async () => {
  const elements = renderHogeComponent();
  const inputBox = elements.inputBox;
  const addButton = elements.addButton;
  const inputText = "My name is Hoge";

  await userEvent.type(inputText);
  await userEvent.click(addButton);

  // ...アサーション略
});

たった2行増えただけなのですが、いきなり認知負荷が爆増しませんか?

本当にちょっとしたことではありますが、

  • 分割代入を使うとコードがスッキリ記述できる
  • 他の人が読んだ時に理解しやすいコードに近づけられる
    といった恩恵がありますのでぜひ積極的に分割代入を取り入れてください。
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?