ボタンを押したら、該当の要素が増える機能を実装していきます。
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;
}
今回は、配列の中に該当のオブジェクトを格納し、それを追加することでレンダリングが走り、新しいアイテムが表示される仕組みとなるので、stateで管理する配列を定義します。
この際、先ほど作成したitem型のみが格納される配列であることを定義するため、型引数として'<Item[]>’を定義します。
const [items, setItems] = useState<Item[]>([]);
クリック時にオブジェクトが配列に格納される関数を作成します。
const addItem = () => {
const newItem: Item = {
id: items.length + 1,
};
setItems([...items, newItem]);
};
Item型を用いたオブジェクトを、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要素が表示される形になりました。