オブジェクトの配列があります。 「this」キーワードを使用せずに配列からオブジェクトを削除する関数を追加する必要があります。
updateList(list.slice(list.indexOf(e.target.name, 1)))
を使ってみました。これにより、配列の最後の項目以外のすべてが削除されますが、理由はわかりません。
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }]
const [list, updateList] = useState(defaultList);
const handleRemoveItem = e => {
updateList(list.slice(list.indexOf(e.target.name, 1)))
}
return (
{list.map(item => {
return (
<>
<span onClick={handleRemoveItem}>x </span>
<span>{item.name}</span>
</>
)}
}
)
期待:クリックされたアイテムはリストから削除されます。
ACTUAL:リスト全体が削除されますが、配列の最後のアイテムは削除されます。
ご意見をお寄せいただきありがとうございます。
まず、クリックイベントのあるspan
要素にはname
プロパティが必要です。それ以外の場合、_e.target
_内に検索する名前はありません。つまり、_e.target.name
_はフォーム要素(入力、選択など)用に予約されています。したがって、実際にnameプロパティを利用するには、e.target.getAttribute("name")
を使用する必要があります
さらに、オブジェクトの配列があるため、list.indexOf(e.target.name)
を使用することは効果的ではありません。オブジェクトを反復処理するときにstring
を探しているためです。それは_[{}, {}, {}]
_内でfind "dog"と言うようなものです
最後に、array.slice()
は新しい配列を返しますインデックスの項目から開始渡した配列。したがって、最後のアイテムをクリックすると、最後のアイテムのみが返されます。
代わりに.filter()
を使用して、次のようなことを試してください: codesandbox
_import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const App = () => {
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }
];
const [list, updateList] = useState(defaultList);
const handleRemoveItem = (e) => {
const name = e.target.getAttribute("name")
updateList(list.filter(item => item.name !== name));
};
return (
<div>
{list.map(item => {
return (
<>
<span name={item.name} onClick={handleRemoveItem}>
x
</span>
<span>{item.name}</span>
</>
);
})}
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
_
Array.filter を使用して、これをワンライナーで行うことができます。
const handleRemoveItem = name => {
updateList(list.filter(item => item.name !== name))
}
Eta:onClickハンドラーでアイテムの名前を渡す必要もあります。
{list.map(item => {
return (
<>
<span onClick={() =>handleRemoveItem(item.name)}>x </span>
<span>{item.name}</span>
</>
)}
この関数を使用して、状態を変更せずにReactの状態配列からアイテムを削除できます。
const handleRemoveItem = name => {
updateList(list => list.filter(item => item.name !== name));
}
サンドボックス: https://codesandbox.io/s/ecstatic-goldwasser-76zop?fontsize=14
私は同じ問題に直面し、この質問の回答を使用して修正しました。ここに行くには複数の答えを使わなければならなかったので、ここに答えを入れます。
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }
]
const [list, updateList] = useState(defaultList);
const handleRemoveItem = idx => {
// assigning the list to temp variable
const temp = [...list];
// removing the element using splice
temp.splice(idx, 1);
// updating the list
updateList(temp);
}
return (
{list.map((item, idx} => {
return (
<div key={idx}>
<span onClick={() =>handleRemoveItem(idx)}>x </span>
<span>{item.name}</span>
</div>
)}
}
)
このコードはうまくいくと思います
let targetIndex = list.findIndex((each) => {each.name == e.target.name});
list.splice(targetIndex-1, 1);
オブジェクト内の名前の値をチェックする必要があるため、代わりにfindIndexを使用します。次に、オブジェクトをターゲットインデックスから、ターゲットインデックスの後の1つの配列に切り取ります。
あなたのコメントからあなたの問題は別の部分から来ました。
このビューセクションを変更
return (
<>
<span onClick={() => handleRemoveItem(item) }>x </span>
<span>{item.name}</span>
</>
)}
関数handleRemoveItemフォーマットを変更する
const handleRemoveItem = item => {
list.splice(list.indexOf(item)-1, 1)
updateList(list);
}