我正在从我的firebase服务器获取JSON数据,有时,它有无序的字段。
我想运行一个useEffect当内容json对象的变化…但是,尝试执行以下操作
useEffect(() => {}, [JSON.stringify(data)]);
不能正常工作,因为无序字段。
我做了一个零食,模拟我现在的情况。
我该如何解决这个问题?
注意:似乎最好避免状态更新…什么好主意吗?
从这个答案:https://stackoverflow.com/a/3849480/8861638
我们可以用这个函数对两个对象进行深度比较,因为它使用递归,所以它可以保证一直进行下去。
function countProps(obj) {
var count = 0;
for (k in obj) {
if (obj.hasOwnProperty(k)) {
count++;
}
}
return count;
};
function objectEquals(v1, v2) {
if (typeof(v1) !== typeof(v2)) {
return false;
}
if (typeof(v1) === "function") {
return v1.toString() === v2.toString();
}
if (v1 instanceof Object && v2 instanceof Object) {
if (countProps(v1) !== countProps(v2)) {
return false;
}
var r = true;
for (k in v1) {
r = objectEquals(v1[k], v2[k]);
if (!r) {
return false;
}
}
return true;
} else {
return v1 === v2;
}
}
现在,我们可以利用objectEquals
函数对该组件中的新数据和现有数据进行比较。
首先,我们想要跟踪数据,以便我们可以将其与未来的数据进行比较,我们可以全面使用useRef
钩子,这样我们就不会触发任何重新渲染。
// data is our initial state.
const savedData = useRef(data || {});
然后,我们可以定制useEffect
来听savedData
与新来的数据的比较,看是否有变化。
const dataChanged = objectEquals(data, savedData.current);
useEffect(() => {
if (dataChanged) {
savedData.current = data;
// Do something...
}
}, [dataChanged])