📘
ReactのState配列操作
State配列
ReactでState配列を表示したり操作するUIはよくあると思います。しかし、ReactのState配列ならではの注意点があり、使うメソッドを気をつける必用があります。
例えば、State配列末尾に追加する場合はpush
では無くconcat
を使う必要があります。
理由は、配列を書き換えずに更新する必用がある為です。
それでは、よく使う操作を説明いたします。
追加
useArray
にaddItem
を実装しました。
concat
を使用して追加するコードです。重要な部分は以下の通りです。
-
ベースの配列.concat(追加したい値)
です -
concat
で新しい値を追加します
import { useState } from 'react';
type Item = {
id: number;
name: string;
};
export const useArray = () => {
const [state, setState] = useState<Item[]>([]);
return {
items: state,
/**
* 末尾に追加
* concatを使用
*/
addItem: () =>
setState((_state) =>
_state.concat({
id: _state.length + 1,
name: '追加された値',
}),
),
};
};
const Component: React.FC = () => {
const { items, addItem } = useArray();
return (
<>
<button onClick={addItem}>追加</button>
<ul>
{items.map((item) => (
<li key={item.id}>{JSON.stringify(item)}</li>
))}
</ul>
</>
);
};
操作シーン
削除
useArray
にremoveItem
を実装しました。
filter
を使用して配列の要素除外するコードです。重要な部分は以下の通りです。
-
ベースの配列.filter(条件)
です - 条件に一致した要素を配列から除外します
-
高階関数を使い
id
を束縛するとシンプルに実装できます
import { useState } from 'react';
type Item = {
id: number;
name: string;
};
export const useArray = () => {
const [state, setState] = useState<Item[]>([]);
return {
items: state,
/**
* 末尾に追加
* concatを使用
*/
addItem: () =>
setState((_state) =>
_state.concat({
id: _state.length + 1,
name: '追加された値',
}),
),
/**
* 要素を削除
* filterを使用
*/
removeItem: (selectedId: Item['id']) => () =>
setState((_state) => _state.filter((o) => o.id !== selectedId)),
};
};
const Component: React.FC = () => {
const { items, addItem, removeItem } = useArray();
return (
<>
<button onClick={addItem}>追加</button>
<ul>
{items.map((item) => (
<li key={item.id}>
{JSON.stringify(item)}
<button onClick={removeItem(item.id)}>削除</button>
</li>
))}
</ul>
</>
);
};
操作シーン
置換
useArray
にreplaceItem
を実装しました。
map
を使用して配列の要素置換するコードです。重要な部分は以下の通りです。
-
ベースの配列.map(条件と値)
です- 条件に一致する場合は、新しい値を返却する
- 条件に一致しない場合は、そのまま値を返却する
-
高階関数を使い
id
を束縛するとシンプルに実装できます
import { useState } from 'react';
type Item = {
id: number;
name: string;
};
export const useArray = () => {
const [state, setState] = useState<Item[]>([]);
return {
items: state,
/**
* 末尾に追加
* concatを使用
*/
addItem: () =>
setState((_state) =>
_state.concat({
id: _state.length + 1,
name: '追加された値',
}),
),
/**
* 要素を削除
* filterを使用
*/
removeItem: (selectedId: Item['id']) => () =>
setState((_state) => _state.filter((o) => o.id !== selectedId)),
/**
* 要素を置換
* mapを使用
*/
replaceItem: (selectedId: Item['id']) => () =>
setState((_state) =>
_state.map((o) =>
o.id === selectedId ? { ...o, name: '置換された値' } : o,
),
),
};
};
const Component: React.FC = () => {
const { items, addItem, removeItem, replaceItem } = useArray();
return (
<>
<button onClick={addItem}>追加</button>
<ul>
{items.map((item) => (
<li key={item.id}>
{JSON.stringify(item)}
<button onClick={removeItem(item.id)}>削除</button>
<button onClick={replaceItem(item.id)}>置換</button>
</li>
))}
</ul>
</>
);
};
操作シーン
降順にソート
useArray
にorderByDesc
を実装しました。
toReversed
を使用して配列を降順にするコードです。重要な部分は以下の通りです。
-
reverse
ではなく、toReversed
を使用する
import { useState } from 'react';
type Item = {
id: number;
name: string;
};
export const useArray = () => {
const [state, setState] = useState<Item[]>([]);
return {
items: state,
/**
* 末尾に追加
* concatを使用
*/
addItem: () =>
setState((_state) =>
_state.concat({
id: _state.length + 1,
name: '追加された値',
}),
),
/**
* 要素を削除
* filterを使用
*/
removeItem: (selectedId: Item['id']) => () =>
setState((_state) => _state.filter((o) => o.id !== selectedId)),
/**
* 要素を置換
* mapを使用
*/
replaceItem: (selectedId: Item['id']) => () =>
setState((_state) =>
_state.map((o) =>
o.id === selectedId ? { ...o, name: '置換された値' } : o,
),
),
/**
* 降順にソート
* toReversedを使用
*/
orderByDesc: () => setState((_state) => _state.toReversed()),
};
};
const Component: React.FC = () => {
const { items, addItem, removeItem, replaceItem, orderByDesc } = useArray();
return (
<>
<div>
<button onClick={addItem}>追加</button>
<button onClick={orderByDesc}>降順</button>
</div>
<ul>
{items.map((item) => (
<li key={item.id}>
{JSON.stringify(item)}
<button onClick={removeItem(item.id)}>削除</button>
<button onClick={replaceItem(item.id)}>置換</button>
</li>
))}
</ul>
</>
);
};
操作シーン

ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion