logo 公式Webサイト

パワフルな
ブログ

ボタンを押したら要素が増える機能を、型引数・useStateを用いて実装【TypeScript,Next.js,React】

2024年4月18日

ボタンを押したら、該当の要素が増える機能を実装していきます。
useStateで、要素情報を配列オブジェクトで管理(IDを付番)、ボタンがクリックされたら定義したオブジェクトに新しいIDがインクリメントされてstateに格納され、レンダリングが走りオブジェクト情報に乗っ取った要素が増える仕組みとなります。
型安全性を保つために、後ほど使用するオブジェクトを型として定義し、useStateの型引数に定義した型を取得し、定義したオブジェクトと型以外は使用されないよう、型安全性を考慮した形となります。

全体のコード

import { useState } from 'react';

type Item = {
  id: number;
}

const [items, setItems] = useState<Item[]>([]);

const addItem = () => {
  const newItem: Item = {
    id: items.length + 1,
  };

  setItems([...items, newItem]);
};

function createItem() {
  return(
    <>
     {items.map((item) => (
       <React.Fragment key={item.id}>
         <div>
           <input type="text" id={item.id} />
         </div>
       </React.Fragment>
     ))}
     <button onClick={addItem}>アイテム追加</button>
    </>
  );
}

型名を宣言

今回使用する型の宣言を行います。

type Item = {
  id: number;
}

useStateで配列を管理

今回は、配列の中に該当のオブジェクトを格納し、それを追加することでレンダリングが走り、新しいアイテムが表示される仕組みとなるので、stateで管理する配列を定義します。
この際、先ほど作成したitem型のみが格納される配列であることを定義するため、型引数として'<Item[]>’を定義します。

const [items, setItems] = useState<Item[]>([]);

ボタンクリック時の関数を定義

クリック時にオブジェクトが配列に格納される関数を作成します。

const addItem = () => {
  const newItem: Item = {
    id: items.length + 1,
  };

  setItems([...items, newItem]);
};

Item型を用いたオブジェクトを、setItems内で既存の値に追加するように記述します。

setItemsの中身を出力

return内でmapメソッドを用いて、配列内にあるオブジェクトの値をセットしたアイテムを出力します。

{items.map((item) => (
<React.Fragment key={item.id}>
  <div>
    <input type="text" id={item.id} />
  </div>
</React.Fragment>
))}
<button onClick={addItem}>アイテム追加</button>

これでボタンを押下することで、該当のinput要素が表示される形になりました。