我做了一个CRUD(仅限UI)简单组件,但是如何让主要联系人成为我表中的第一个?该应用程序可以执行crud,检查和取消选中主要联系人,表中只允许一个主要联系人。
工作演示 https://codesandbox.io/s/r7kmp9rkom
=============================================== =
我尝试过使用lodash的sortBy
(使用sortBy破解演示 https://codesandbox.io/s/pjj3098lmx)
第130行
<tbody>
{sortBy(contacts, o => !o.primary).map((o, i) => {
return (
<tr className={classNames({ primary: o.primary })} key={i}>
<td>{o.name}</td>
<td>{o.email}</td>
<td>
<button
onClick={() =>
this.setState({
openModal: true,
modalAction: "update",
selected_contact: o,
selected_contact_index: i
})
}
>
Edit
</button>
</td>
</tr>
);
})}
</tbody>
但它破坏了功能。我认为这与索引问题有关。
我无法解决它我不知道为什么sortBy不保留索引。另一个愚蠢的选择是使用flexbox命令,但我希望我可以使用javascript解决它。
答案 0 :(得分:0)
正如你所说,这是一个索引问题
我使用lodash的uniqueId方法来保留id
值,当我们进行删除/更新/添加等操作时,永远不要将索引用作key
作为动态列表。
如果应用是服务器端渲染,则id
必须来自后端。
id: uniqueId("contact_")
static defaultProps = {
data: {
contacts: [
{
name: "James",
email: "james@havard.edu",
primary: false,
id: uniqueId("contact_")
},
{
name: "Mark",
email: "mark@standford.edu",
primary: true,
id: uniqueId("contact_")
}
]
}
};
onSaveContact = (action, newContact, newContact_index) => {
if (action === "add") {
if (newContact.primary) {
const setNonePrimary = this.state.contacts.map(o => ({
...o,
primary: false
}));
this.setState({
contacts: [
...setNonePrimary,
{ ...newContact, id: uniqueId("contact_") }
]
});
} else {
this.setState({
contacts: [
...this.state.contacts,
{ ...newContact, id: uniqueId("contact_") }
]
});
}
} else if (action === "update") {
this.setState({
contacts: [
...this.state.contacts.map((o, i) => {
if (o.id === newContact_index) {
return { ...newContact };
} else {
if (newContact.primary) {
return { ...o, primary: false };
} else {
return { ...o };
}
}
})
]
});
} else if (action === "delete") {
this.setState({
contacts: [
...this.state.contacts.filter((o, i) => {
if (o.id !== newContact_index) {
return o;
}
})
]
});
}