【发布时间】:2021-06-11 12:43:37
【问题描述】:
我有以下代码,这是我上一个问题的答案,但我不想弄乱question,而是想重申我真正在寻找的东西,因为我似乎无法掌握它。
我想要的预期输出现在只是一个具有更改值和 id 的对象。但是,这需要更改,因此它不会像现在的代码那样堆叠,每次实例更改时都会有另一个对象受到控制。我只想让最新的比较得到安慰,而忽略前一个。希望这是有道理的。如果需要,我可以进一步解释。
当我说堆叠时,我的意思是,下次状态改变时它控制两个项目,然后是三个,依此类推,第四个。我只想要最新的更改,以便我可以运行突变并更新我的数据库
状态改变后的期望结果#1
{col0:"snappy", col10:"292959180223939085"}
状态改变后的期望结果#2
{col0:"some state change", col10:"292959180223939085"}
const oldState = [{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "okok",
"col3": true,
"col4": 7,
"col5": 5,
"col6": "Curation",
"col7": "fsaf",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615646495/catalog/sse5zxtklsj3ib730zjy.png",
"col9": 4,
"col10": "292959180223939085"
},
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "fdsafd",
"col3": true,
"col4": 3,
"col5": 3,
"col6": "Curation",
"col7": "fdsfsa",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615657360/catalog/qpudbgkrvftjlo5c1yma.png",
"col9": 5,
"col10": "292970573359743501"
}
]
const saveData = [{
"col0": "Snappy",
"col1": "2021-03-31",
"col2": "okok",
"col3": true,
"col4": 7,
"col5": 5,
"col6": "Curation",
"col7": "fsaf",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615646495/catalog/sse5zxtklsj3ib730zjy.png",
"col9": 4,
"col10": "292959180223939085"
},
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "fdsafd",
"col3": true,
"col4": 3,
"col5": 3,
"col6": "Curation",
"col7": "fdsfsa",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615657360/catalog/qpudbgkrvftjlo5c1yma.png",
"col9": 5,
"col10": "292970573359743501"
}
]
function compareArray(oldItem, newItem) {
const compared = {};
for (const key in oldItem) {
if ((key == 'col10' || oldItem[key] != newItem[key]) && Object.hasOwnProperty.call(newItem, key) && Object.hasOwnProperty.call(oldItem, key)) {
compared[key] = newItem[key];
}
}
return compared;
}
oldState.map((old, i) => [old, saveData[i]]).forEach((item) => console.log(compareArray(...item)));
这是我的实现方式,saveData 状态依赖于到达 useState,所以它总是在变化。
function AutoSave({ saveData, cookieBearer, oldState }) {
const [saving, setSaving] = useState(false);
const [
updateDecorDoc,
{ data: docData, loading: savingMutate },
] = useMutation(UPDATE_DECOR_DOC, {
context: {
headers: {
authorization: cookieBearer,
},
},
});
const debounceSave = useCallback(
debounce(async (saveData) => {
setSaving(true);
function compareArray(oldItem, newItem) {
const compared = {};
for (let key in oldItem) {
if (oldItem[key] != newItem[key]) {
compared[key] = newItem[key];
compared["col10"] = newItem["col10"];
}
}
return compared;
}
oldState
.map((old, i) => [old, saveData[i]])
.forEach((item) => {
var test = compareArray(...item);
console.log(test)
});
})
);
useEffect(() => {
if (saveData) {
debounceSave(saveData);
}
}, [saveData, debounceSave]);
if (saving) return <p>saving</p>;
if (!saving) return <p>Auto Save on</p>;
}
更新:每次比较后它都会向对象添加属性,我希望每次我的 onblur 事件触发时只有最近更改的属性,这意味着用户已经离开输入并且我触发了我的保存突变。
这是一个屏幕截图,显示了对象中的多个属性,它应该只有一个,然后是 ID。它应该一起替换对象而不是每次比较都添加到它。数组中还有两个对象,我只需要最近更改的一个,因为我在每次比较时都会触发保存突变,并且只需要一个具有两个字段的对象,即更改的字段和 id。
【问题讨论】:
-
您使用的
compareArray函数不是我的最终编辑,但您实现它的方式使col10键重新初始化为 @987654331 中每个键的新状态@ 目的。使用我从另一个问题中完成的功能。 -
当您询问
col10键时,我在最后一个问题中编辑了我的答案。你又运行了 sn-p 吗? -
sn-p 给了我两个对象,并且在 react 中的每个新数据更改时,都会添加另外两个对象。所以它并不能完全解决我的问题。如果有意义的话,我只需要当前的更改状态对象而不是以前的更改状态对象
-
我不明白你的意思,该函数返回两对对象之间的不同之处并返回。每个对象中有两个元素。这意味着它总是返回
oldState或saveData数组的长度 -
这很难解释,你的回答有些正确。我只是在解释我需要什么方面做得不好。我会尽快在这里更新我的问题,并提供更好的细节。感谢您迄今为止的帮助
标签: javascript reactjs lodash autosave array.prototype.map