JavaScript:値渡し?参照渡し?

コンポーネントを純粋に保つ – Reactのチャレンジ問題の最後でハマってしまいました😅ハマったのは下記コード:

export default function StoryTray({ stories }) {
  let storiesTray = stories;
  storiesTray.push({
    id: "create",
    label: "Create Story",
  });

  return (
    <ul>
      {storiesTray.map((story) => (
        <li key={story.id}>{story.label}</li>
      ))}
    </ul>
  );
}

問題なのは let storiesTray = stories; の部分で、ここが値渡しでやっていると勘違いして、結構詰まりました、、、

JavaScript ではプリミティブは値渡しで、オブジェクトは参照渡しになるということなので、上記は storiesTray.push で意図せず呼び出し元のオブジェクトを更新するようになってしまっていました😅

回避するには StoryTray コンポーネント内にローカルインスタンスを用意してあげればいいので、let storiesTray = stories.slice() として配列をコピーしてあげれば良い。

export default function StoryTray({ stories }) {
  let storiesTray = stories.slice();
  ...
}

配列操作では、使用するメソッドが破壊的かどうかを覚えておくことが有効とのこと。

破壊的かどうかについては、[JavaScript] Arrayメソッド破壊・非破壊チートシート - Qiitaの記事がとても参考になりました👀