当我按下删除按钮时,它每次都仅删除最后一个元素,而不管索引如何。
我该怎么做呢?无需在子组件中将<input defaultValue={name} />
更改为<input value={name} />
,我已经用<input defaultValue={name} />
完成了,但是如何使用输入的value
属性呢?
export const App = () => {
const [names, setNames] = React.useState([
"First",
"Second",
"third",
"fourth",
]);
const onChange = (params) => {
doing(params); // etc.
};
function onDelete(index: number) {
const nameArr = [...names];
nameArr.splice(index, 1);
setNames(nameArr);
}
return (
<div>
{names.map((name, index) => (
<ChildComponent
key={index}
name={name}
index={index}
onChange={onChange}
onDelete={handleDelete}
/>
))}
</div>
);
};
const ChildComponent = React.memo(({ name, index, onChange, onDelete }) => {
return (
<div>
<input
defaultValue={name}
onChange={(event) => onChange(index, event.target.value)}
/>
<button onClick={() => onDelete(index)}>delete</button>
</div>
);
});
答案 0 :(得分:0)
您的代码中有错字(onDelete
和handleDelete
),但这不是主要问题。您的问题是使用index
作为key
。由于您要删除附加到状态的某些元素,因此React index
不可信任,因此无法决定如何再次对数组排序。
您应该为密钥使用一些唯一的值,如果没有,则应以某种方式创建它们。在下面的示例中,我尝试将index
与以下值混合:
key={`${index}${name}`}
此外,请勿使用类似splice的方法,因为它们会改变状态。 splice
将元素更改到位,因此进行了更改。我使用了filter,但是您可以使用任何其他不会改变状态的方法。
function App() {
const [names, setNames] = React.useState([
"First",
"Second",
"third",
"fourth"
]);
function onDelete(index) {
setNames((prev) => prev.filter((_, i) => i !== index));
}
return (
<div>
{names.map((name, index) => (
<ChildComponent
key={`${index}${name}`}
name={name}
index={index}
onDelete={onDelete}
/>
))}
</div>
);
}
const ChildComponent = React.memo(({ name, index, onChange, onDelete }) => {
return (
<div>
<input
defaultValue={name}
onChange={(event) => onChange(index, event.target.value)}
/>
<button onClick={() => onDelete(index)}>delete</button>
</div>
);
});
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />