JavaScript、React、Reduxでアイテムを削除:初心者向けチュートリアル
JavaScript、React、Reduxにおけるアイテムの削除方法
Redux でアイテムを削除するには、いくつかの方法があります。ここでは、最も一般的な 2 つの方法をご紹介します。
filter
関数は、配列から条件に合致する要素を削除するのに役立ちます。Redux ストア内のアイテムを削除するには、次のように filter
関数を使用できます。
const initialState = {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
],
};
function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_ITEM':
const filteredItems = state.items.filter(item => item.id !== action.payload);
return {
...state,
items: filteredItems,
};
default:
return state;
}
}
このコードでは、DELETE_ITEM
というアクションタイプがディスパッチされたときに filter
関数を使用してアイテムが削除されます。action.payload
には、削除するアイテムの ID が含まれます。
immer ライブラリを使う
immer
は、イミュータブルなデータを操作するためのライブラリです。Redux ストア内のアイテムを削除するには、次のように immer
ライブラリを使用できます。
const initialState = {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
],
};
function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_ITEM':
return produce(state, draft => {
draft.items = draft.items.filter(item => item.id !== action.payload);
});
default:
return state;
}
}
このコードでは、immer
ライブラリの produce
関数を使用してアイテムが削除されます。produce
関数は、イミュータブルなデータを操作できるように、状態のスナップショットを渡します。
どちらの方法を使うべきかは、個人の好みとプロジェクトの要件によって異なります。
filter
関数はシンプルで理解しやすいですが、パフォーマンスが低くなる可能性があります。immer
ライブラリはパフォーマンスが優れていますが、コードが少し複雑になります。
その他の注意点
- アイテムを削除する前に、そのアイテムに依存している他のコンポーネントがないことを確認してください。
- アイテムを削除した後は、UI を更新する必要があります。
補足
- 上記のコードはあくまで例であり、プロジェクトの要件に合わせて変更する必要があります。
- Redux には、アイテムを削除するための他の方法もあります。
このコード例では、Redux を使用してシンプルな ToDo リスト アプリケーションを作成します。このアプリでは、ユーザーはアイテムを追加、編集、削除できます。
ファイル構成
actions.js
- アクション定義reducer.js
- リデューサーApp.js
- メインコンポーネント
actions.js
export const ADD_ITEM = 'ADD_ITEM';
export const DELETE_ITEM = 'DELETE_ITEM';
export const EDIT_ITEM = 'EDIT_ITEM';
export const addItem = (text) => ({
type: ADD_ITEM,
payload: text,
});
export const deleteItem = (id) => ({
type: DELETE_ITEM,
payload: id,
});
export const editItem = (id, text) => ({
type: EDIT_ITEM,
payload: {
id,
text,
},
});
reducer.js
import { ADD_ITEM, DELETE_ITEM, EDIT_ITEM } from './actions';
const initialState = {
items: [],
};
function reducer(state = initialState, action) {
switch (action.type) {
case ADD_ITEM:
return {
...state,
items: [...state.items, { id: state.items.length + 1, text: action.payload }],
};
case DELETE_ITEM:
return {
...state,
items: state.items.filter(item => item.id !== action.payload),
};
case EDIT_ITEM:
return {
...state,
items: state.items.map(item => {
if (item.id === action.payload.id) {
return { ...item, text: action.payload.text };
}
return item;
}),
};
default:
return state;
}
}
export default reducer;
App.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Item from './Item';
import reducer from './reducer';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
const store = createStore(reducer);
function App() {
const dispatch = useDispatch();
const items = useSelector(state => state.items);
const handleAddItem = (text) => {
dispatch(addItem(text));
};
const handleDeleteItem = (id) => {
dispatch(deleteItem(id));
};
const handleEditItem = (id, text) => {
dispatch(editItem(id, text));
};
return (
<div>
<h1>ToDo リスト</h1>
<input type="text" placeholder="新しいアイテムを追加..." onChange={(event) => handleAddItem(event.target.value)} />
<ul>
{items.map(item => (
<Item
key={item.id}
id={item.id}
text={item.text}
onDelete={() => handleDeleteItem(item.id)}
onEdit={(text) => handleEditItem(item.id, text)}
/>
))}
</ul>
</div>
);
}
export default App;
Item.js
import React from 'react';
function Item({ id, text, onDelete, onEdit }) {
const [isEditing, setIsEditing] = React.useState(false);
const [editText, setEditText] = React.useState(text);
const handleEdit = () => {
setIsEditing(true);
};
const handleSave = () => {
onEdit(editText);
setIsEditing(false);
};
const handleCancel = () => {
setIsEditing(false);
};
return (
<li>
{isEditing ? (
<input type="text" value={editText} onChange={(event) => setEditText(event.target.value)} />
) : (
<span onClick={handleEdit}>{text}</span>
)}
<button onClick={onDelete}>削除</button>
{isEditing && <button onClick={handleCancel}>キャンセル</button>}
{isEditing && <button
Redux でアイテムを削除するその他の方法
const initialState = {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
],
};
function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_ITEM':
const filteredItems = state.items.reduce((acc, item) => {
if (item.id !== action.payload) {
acc.push(item);
}
return acc;
}, []);
return {
...state,
items: filteredItems,
};
default:
return state;
}
}
このコードでは、reduce
関数は新しい空の配列 acc
を引数として受け取ります。 次に、配列の各要素をループし、item.id
が action.payload
と等しくない場合は acc
に追加します。 最後に、filteredItems
を state.items
に設定します。
長所:
- シンプルで理解しやすい
filter
関数よりもパフォーマンスが低くなる可能性がある
lodash ライブラリを使う
lodash
は、JavaScript に便利なユーティリティ関数を提供するライブラリです。 Redux ストア内のアイテムを削除するには、次のように lodash
ライブラリを使用できます。
const initialState = {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
],
};
function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_ITEM':
const filteredItems = _.remove(state.items, item => item.id === action.payload);
return {
...state,
items: filteredItems,
};
default:
return state;
}
}
このコードでは、_.remove
関数は state.items
配列から item.id
が action.payload
と等しい要素を削除します。
filter
関数やreduce
関数よりもコードが簡潔になる
- プロジェクトに
lodash
ライブラリを追加する必要がある
const initialState = Immutable.fromJS({
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
],
});
function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_ITEM':
const filteredItems = state.get('items').filterNot(item => item.get('id') === action.payload);
return state.set('items', filteredItems);
default:
return state;
}
}
- イミュータブルなデータ構造を安全かつ効率的に操作できる
- シンプルで理解しやすい方法が必要な場合は、
filter
関数を使用するのが良いでしょう。 - パフォーマンスが
javascript reactjs redux