【今日からできる】React初心者のコードを改善する3つのtips

## はじめに
この記事は[4 React Tips to Instantly Improve Your Code](https://javascript.plainenglish.io/4-react-tips-to-instantly-improve-your-code-7456e028cfa3 "タイトル")を日本語に翻訳したものです。リンク先の記事では4つのtipsが紹介されていますが、今日からすぐに使えそうなtipsは3つであるため(一つは初心者が理解するには難しそう)今回は3つ抜粋して紹介します。
興味ある方はぜひ翻訳元の記事を読んでみてください。

### Return functions from handlers

まずはこちらのコードをご覧ください。

``` React
export default function App() {
  const [user, setUser] = useState({
    name: "",
    surname: "",
    address: ""
  });

  // First handler
  const handleNameChange = (e) => {
    setUser((prev) => ({
      ...prev,
      name: e.target.value
    }));
  };

  // Second handler!
  const handleSurnameChange = (e) => {
    setUser((prev) => ({
      ...prev,
      surname: e.target.value
    }));
  };

  // Third handler!!!
  const handleAddressChange = (e) => {
    setUser((prev) => ({
      ...prev,
      address: e.target.value
    }));
  };

  // What if we need one more input? Should we create another handler for it?

  return (
    <>
      <input value={user.name} onChange={handleNameChange} />
      <input value={user.surname} onChange={handleSurnameChange} />
      <input value={user.address} onChange={handleAddressChange} />
    </>
  );
}
```

どこが改善できるポイントかお分かりいただけたでしょうか？
そう、ポイントは`state`の値を変更するために三つの関数を定義しているところです。

`user`のプロパティが例では三つですが、これがメールアドレスや住所など他にも増えるとしたらかなり冗長ですよね。

こういったオブジェクトを更新する関数は実は一つにまとめてDRYに書くことができます。

実際のコードがこちら。

``` React
export default function App() {
  const [user, setUser] = useState({
    name: "",
    surname: "",
    address: ""
  });

  const handleInputChange = (field) => {
    return (e) => {
      setUser((prev) => ({
        ...prev,
        [field]: e.target.value
      }));
    };
  };

  return (
    <>
      <input value={user.name} onChange={handleInputChange("name")} />
      <input value={user.surname} onChange={handleInputChange("surname")} />
      <input value={user.address} onChange={handleInputChange("address")} />

      {JSON.stringify(user)}
    </>
  );
}
```

関数が一つにまとめられていてかなりスッキリしましたね。
`handleInputChange`のロジックは`prev`で現在の`user`の情報を取得し、オブジェクトの中でスプレッド構文を使って展開、その後、引数に渡された該当の`field`キーを更新するという流れです。

React初心者の人はよくやりがちなコードで、私も最初はこのように書いていました。。


### Use objects map instead of conditions

続いてのコードはこちらです。

``` React
function Account({type}) {
  let Component = UsualAccount

  if (type === 'vip') {
    Component = VipAccount
  }

  if (type === 'moderator') {
    Component = ModeratorAccount
  }

  if (type === 'admin') {
    Component = AdminAccount
  }

  return (
    <div className='account'>
      <Component />
      <AccountStatistics />
    </div>
  )
}
```

こちらもどこが改善できそうか予測できますね。
こちらのコードの改善ポイントは条件分岐です。

ではこのコードをどのようにリファクタできるのか。リファクタ後のコードを見てみましょう。

``` React
const ACCOUNTS_MAP = {
  'vip': VipAccount,
  'usual': UsualAccount,
  'admin': AdminAccount,
  'moderator': ModeratorAccount,
}

function Account({type}) {
  const Component = ACCOUNTS_MAP[type]

  return (
    <div className='account'>
      <Component />
      <AccountStatistics />
    </div>
  )
}
```

変更箇所はif文を使って`Component`にエレメントを代入しているのではなく、　オブジェクトを使ってエレメントを代入しているところです。

これも初心者がやってしまいがちな書き方ですね。。

### Put independent variables outside of React lifecycle

最後に紹介するtipsはこちらです。

``` React
function useItemsList() {
  const defaultItems = [1, 2, 3, 4, 5]
  const [items, setItems] = useState(defaultItems)

  const toggleArrayItem = (arr, val) => {
    return arr.includes(val) ? arr.filter(el => el !== val) : [...arr, val];
  }

  const handleToggleItem = (num) => {
    return () => {
      setItems(toggleArrayItem(items, num))
    }
  }

  return {
    items,
    handleToggleItem,
  }
}
```

続いて改善後のコードがこちらです。

``` React
const DEFAULT_ITEMS = [
  1, 2, 3, 4, 5
]

const toggleArrayItem = (arr, val) => {
  return arr.includes(val) ? arr.filter(el => el !== val) : [...arr, val];
}

function useItemsList() {
  const [items, setItems] = useState(DEFAULT_ITEMS)

  const handleToggleItem = (num) => {
    return () => {
      setItems(toggleArrayItem(items, num))
    }
  }

  return {
    items,
    handleToggleItem,
  }
}
```

どこが変更されたのか、なぜその変更がされたのかお分かりいただけましたでしょうか？

まず変更された点に関しては`DEFAULT_ITEMS`と`toggleArrayItem`がコンポーネントの外に定義されたところです。

ではなぜ、この変更が行われたのか。
それはライフサイクル、メソッドを必要としない変数や関数をコンポーネントから分離することで依存関係が明確になり、コードリーディングがしやすく、コンポーネントを理解しやすくなると筆者は述べています。

今回の例ではコード量が少ないため、その恩恵を受けることが少ないかもしれませんが、コンポーネントが肥大化すると依存関係が複雑になり、コンポーネントを理解するのが難しくなります。

## おわりに
いかがでしたでしょうか？
今回はReact初心者のコードを改善する3つのtipsについて紹介しました。
どれも今日から使えるtipsだと思うのでぜひ、実践してみてください。

今後もこのようなtipsについて紹介していこうと思うのでよければフォロー、いいね、ブックマークよろしくお願いします！