如果没有机会创建唯一密钥怎么办?
What if there is no opportunity to create unique keys?
我有一个复杂的数据集,所以我将展示一个非常简化的版本作为示例。
输入数据:
const data = [
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
}
];
数组中的每一项都是可移动的。结果是这样的。
有几个条件。我不应该修改数据数组,所以我创建了一个深拷贝。同样在副本中,我只能删除元素但不能修改它们的属性。因此每个元素都必须具有具有新值的本地状态。
工作示例:
function App() {
const [mainData, setMainData] = useState(deepCopy(data));
return (
<React.Fragment>
{
mainData.map((item, i) => {
return (
<Input {...item} key={i} num={i} setMainData={setMainData}/>
)
})
}
</React.Fragment>
)
}
const Input = (props) => {
const [value, setValue] = useState(props.defaultValue);
const deleteElem = () => {
props.setMainData((mainData) => {
return [...mainData.filter((_, ind) => ind !== props.num)];
});
};
return (
<div>
<div>
<div>{`${props.caption}:`}</div>
<input value={value} onChange={(e)=>setValue(e.target.value)}/>
</div>
<button onClick={deleteElem}>delete</button>
</div>
)
};
const deepCopy = (aObject) => {
if (!aObject) {
return aObject;
}
let value;
let bObject = Array.isArray(aObject) ? [] : {};
for (const key in aObject) {
value = aObject[key];
bObject[key] = (typeof value === "object") ? deepCopy(value) : value;
}
return bObject;
};
如果您尝试删除的不是最后一个元素,那么(由于键的原因)输入元素的值将会混淆。
我该怎么办?
使用 deepCopy
,您可以在初始化状态时为每个项目添加唯一 ID。完成后,您可以利用该 ID 作为键传递给输入元素
import {uuid} from 'uuidv4';
function deepCopyAndAddId = () => {
let newData = deepCopy(data);
newData = newData.map((item, index) => ({...item, id: uuid()}));
}
function App() {
const [mainData, setMainData] = useState(deepCopyAndAddId);
return (
<React.Fragment>
{
mainData.map((item, i) => {
return (
<Input {...item} key={item.id} num={i} setMainData={setMainData}/>
)
})
}
</React.Fragment>
)
}
要对您的代码进行最少的更改 - 永远不要删除 deleteElem
中的项目,而是向其添加一个标记 deleted
。
渲染项目时,为 deleted
项目显示 <Fragment>
。
我有一个复杂的数据集,所以我将展示一个非常简化的版本作为示例。
输入数据:
const data = [
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
},
{
type: "input",
caption: "Name",
defaultValue: "John Smith"
}
];
数组中的每一项都是可移动的。结果是这样的。
有几个条件。我不应该修改数据数组,所以我创建了一个深拷贝。同样在副本中,我只能删除元素但不能修改它们的属性。因此每个元素都必须具有具有新值的本地状态。
工作示例:
function App() {
const [mainData, setMainData] = useState(deepCopy(data));
return (
<React.Fragment>
{
mainData.map((item, i) => {
return (
<Input {...item} key={i} num={i} setMainData={setMainData}/>
)
})
}
</React.Fragment>
)
}
const Input = (props) => {
const [value, setValue] = useState(props.defaultValue);
const deleteElem = () => {
props.setMainData((mainData) => {
return [...mainData.filter((_, ind) => ind !== props.num)];
});
};
return (
<div>
<div>
<div>{`${props.caption}:`}</div>
<input value={value} onChange={(e)=>setValue(e.target.value)}/>
</div>
<button onClick={deleteElem}>delete</button>
</div>
)
};
const deepCopy = (aObject) => {
if (!aObject) {
return aObject;
}
let value;
let bObject = Array.isArray(aObject) ? [] : {};
for (const key in aObject) {
value = aObject[key];
bObject[key] = (typeof value === "object") ? deepCopy(value) : value;
}
return bObject;
};
如果您尝试删除的不是最后一个元素,那么(由于键的原因)输入元素的值将会混淆。 我该怎么办?
使用 deepCopy
,您可以在初始化状态时为每个项目添加唯一 ID。完成后,您可以利用该 ID 作为键传递给输入元素
import {uuid} from 'uuidv4';
function deepCopyAndAddId = () => {
let newData = deepCopy(data);
newData = newData.map((item, index) => ({...item, id: uuid()}));
}
function App() {
const [mainData, setMainData] = useState(deepCopyAndAddId);
return (
<React.Fragment>
{
mainData.map((item, i) => {
return (
<Input {...item} key={item.id} num={i} setMainData={setMainData}/>
)
})
}
</React.Fragment>
)
}
要对您的代码进行最少的更改 - 永远不要删除 deleteElem
中的项目,而是向其添加一个标记 deleted
。
渲染项目时,为 deleted
项目显示 <Fragment>
。