mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(use-default-subplebbits): prevent state updates after unmount
This commit is contained in:
@@ -95,50 +95,67 @@ export const useDefaultSubplebbits = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isMounted = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// Check localStorage first
|
// Check localStorage first
|
||||||
const cachedData = getFromLocalStorage();
|
const cachedData = getFromLocalStorage();
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
cacheSubplebbits = cachedData.subplebbits;
|
cacheSubplebbits = cachedData.subplebbits;
|
||||||
setState({
|
if (isMounted) {
|
||||||
subplebbits: cachedData.subplebbits,
|
|
||||||
loading: false,
|
|
||||||
error: null,
|
|
||||||
});
|
|
||||||
// Still try to fetch fresh data in background (don't await)
|
|
||||||
fetchMultisubData().then((data) => {
|
|
||||||
cacheSubplebbits = data.subplebbits;
|
|
||||||
setState({
|
setState({
|
||||||
subplebbits: data.subplebbits,
|
subplebbits: cachedData.subplebbits,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
// Still try to fetch fresh data in background (don't await)
|
||||||
|
fetchMultisubData()
|
||||||
|
.then((data) => {
|
||||||
|
if (isMounted) {
|
||||||
|
cacheSubplebbits = data.subplebbits;
|
||||||
|
setState({
|
||||||
|
subplebbits: data.subplebbits,
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.warn('Background fetch failed:', e);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cache, fetch fresh data
|
// No cache, fetch fresh data
|
||||||
const multisub = await fetchMultisubData();
|
const multisub = await fetchMultisubData();
|
||||||
cacheSubplebbits = multisub.subplebbits;
|
if (isMounted) {
|
||||||
|
cacheSubplebbits = multisub.subplebbits;
|
||||||
setState({
|
setState({
|
||||||
subplebbits: multisub.subplebbits,
|
subplebbits: multisub.subplebbits,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Failed to load subplebbits:', e);
|
console.warn('Failed to load subplebbits:', e);
|
||||||
// Fallback to vendored data
|
// Fallback to vendored data
|
||||||
const fallbackData = defaultSubplebbitsData as MultisubData;
|
const fallbackData = defaultSubplebbitsData as MultisubData;
|
||||||
cacheSubplebbits = fallbackData.subplebbits;
|
if (isMounted) {
|
||||||
setState({
|
cacheSubplebbits = fallbackData.subplebbits;
|
||||||
subplebbits: fallbackData.subplebbits,
|
setState({
|
||||||
loading: false,
|
subplebbits: fallbackData.subplebbits,
|
||||||
error: null,
|
loading: false,
|
||||||
});
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// To maintain backward compatibility, return the subplebbits array directly
|
// To maintain backward compatibility, return the subplebbits array directly
|
||||||
@@ -162,50 +179,67 @@ export const useDefaultSubplebbitsState = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isMounted = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// Check localStorage first
|
// Check localStorage first
|
||||||
const cachedData = getFromLocalStorage();
|
const cachedData = getFromLocalStorage();
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
cacheSubplebbits = cachedData.subplebbits;
|
cacheSubplebbits = cachedData.subplebbits;
|
||||||
setState({
|
if (isMounted) {
|
||||||
subplebbits: cachedData.subplebbits,
|
|
||||||
loading: false,
|
|
||||||
error: null,
|
|
||||||
});
|
|
||||||
// Still try to fetch fresh data in background (don't await)
|
|
||||||
fetchMultisubData().then((data) => {
|
|
||||||
cacheSubplebbits = data.subplebbits;
|
|
||||||
setState({
|
setState({
|
||||||
subplebbits: data.subplebbits,
|
subplebbits: cachedData.subplebbits,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
// Still try to fetch fresh data in background (don't await)
|
||||||
|
fetchMultisubData()
|
||||||
|
.then((data) => {
|
||||||
|
if (isMounted) {
|
||||||
|
cacheSubplebbits = data.subplebbits;
|
||||||
|
setState({
|
||||||
|
subplebbits: data.subplebbits,
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.warn('Background fetch failed:', e);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cache, fetch fresh data
|
// No cache, fetch fresh data
|
||||||
const multisub = await fetchMultisubData();
|
const multisub = await fetchMultisubData();
|
||||||
cacheSubplebbits = multisub.subplebbits;
|
if (isMounted) {
|
||||||
|
cacheSubplebbits = multisub.subplebbits;
|
||||||
setState({
|
setState({
|
||||||
subplebbits: multisub.subplebbits,
|
subplebbits: multisub.subplebbits,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Failed to load subplebbits:', e);
|
console.warn('Failed to load subplebbits:', e);
|
||||||
// Fallback to vendored data
|
// Fallback to vendored data
|
||||||
const fallbackData = defaultSubplebbitsData as MultisubData;
|
const fallbackData = defaultSubplebbitsData as MultisubData;
|
||||||
cacheSubplebbits = fallbackData.subplebbits;
|
if (isMounted) {
|
||||||
setState({
|
cacheSubplebbits = fallbackData.subplebbits;
|
||||||
subplebbits: fallbackData.subplebbits,
|
setState({
|
||||||
loading: false,
|
subplebbits: fallbackData.subplebbits,
|
||||||
error: null,
|
loading: false,
|
||||||
});
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
@@ -223,6 +257,9 @@ export const useMultisubMetadata = () => {
|
|||||||
if (cacheMetadata) {
|
if (cacheMetadata) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isMounted = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// Check localStorage first
|
// Check localStorage first
|
||||||
@@ -235,45 +272,61 @@ export const useMultisubMetadata = () => {
|
|||||||
updatedAt: cachedData.updatedAt,
|
updatedAt: cachedData.updatedAt,
|
||||||
};
|
};
|
||||||
cacheMetadata = metadata;
|
cacheMetadata = metadata;
|
||||||
setMetadata(metadata);
|
if (isMounted) {
|
||||||
|
setMetadata(metadata);
|
||||||
|
}
|
||||||
// Still try to fetch fresh data in background (don't await)
|
// Still try to fetch fresh data in background (don't await)
|
||||||
fetchMultisubData().then((data) => {
|
fetchMultisubData()
|
||||||
const freshMetadata: MultisubMetadata = {
|
.then((data) => {
|
||||||
title: data.title,
|
if (isMounted) {
|
||||||
description: data.description,
|
const freshMetadata: MultisubMetadata = {
|
||||||
createdAt: data.createdAt,
|
title: data.title,
|
||||||
updatedAt: data.updatedAt,
|
description: data.description,
|
||||||
};
|
createdAt: data.createdAt,
|
||||||
cacheMetadata = freshMetadata;
|
updatedAt: data.updatedAt,
|
||||||
setMetadata(freshMetadata);
|
};
|
||||||
});
|
cacheMetadata = freshMetadata;
|
||||||
|
setMetadata(freshMetadata);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.warn('Background metadata fetch failed:', e);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cache, fetch fresh data
|
// No cache, fetch fresh data
|
||||||
const multisub = await fetchMultisubData();
|
const multisub = await fetchMultisubData();
|
||||||
const metadata: MultisubMetadata = {
|
if (isMounted) {
|
||||||
title: multisub.title,
|
const metadata: MultisubMetadata = {
|
||||||
description: multisub.description,
|
title: multisub.title,
|
||||||
createdAt: multisub.createdAt,
|
description: multisub.description,
|
||||||
updatedAt: multisub.updatedAt,
|
createdAt: multisub.createdAt,
|
||||||
};
|
updatedAt: multisub.updatedAt,
|
||||||
cacheMetadata = metadata;
|
};
|
||||||
setMetadata(metadata);
|
cacheMetadata = metadata;
|
||||||
|
setMetadata(metadata);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Failed to load metadata, using vendored fallback:', e);
|
console.warn('Failed to load metadata, using vendored fallback:', e);
|
||||||
// Fallback to vendored data
|
// Fallback to vendored data
|
||||||
const fallbackData = defaultSubplebbitsData as MultisubData;
|
const fallbackData = defaultSubplebbitsData as MultisubData;
|
||||||
const metadata: MultisubMetadata = {
|
if (isMounted) {
|
||||||
title: fallbackData.title,
|
const metadata: MultisubMetadata = {
|
||||||
description: fallbackData.description,
|
title: fallbackData.title,
|
||||||
createdAt: fallbackData.createdAt,
|
description: fallbackData.description,
|
||||||
updatedAt: fallbackData.updatedAt,
|
createdAt: fallbackData.createdAt,
|
||||||
};
|
updatedAt: fallbackData.updatedAt,
|
||||||
cacheMetadata = metadata;
|
};
|
||||||
setMetadata(metadata);
|
cacheMetadata = metadata;
|
||||||
|
setMetadata(metadata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return cacheMetadata || metadata;
|
return cacheMetadata || metadata;
|
||||||
|
|||||||
Reference in New Issue
Block a user