fix(share): wxacodeUrl 改用 useRef 避免压缩后引用丢失
This commit is contained in:
@@ -42,7 +42,8 @@ export function SharePage() {
|
|||||||
const [imageUrl, setImageUrl] = useState<string | null>(null);
|
const [imageUrl, setImageUrl] = useState<string | null>(null);
|
||||||
const [linkCopied, setLinkCopied] = useState(false);
|
const [linkCopied, setLinkCopied] = useState(false);
|
||||||
const [canShareToWechat, setCanShareToWechat] = useState(false);
|
const [canShareToWechat, setCanShareToWechat] = useState(false);
|
||||||
const [wxacodeUrl, setWxacodeUrl] = useState<string | null>(null);
|
const wxacodeUrl = useRef<string | null>(null);
|
||||||
|
const [, forceUpdate] = useState(0);
|
||||||
const cardRef = useRef<HTMLDivElement>(null);
|
const cardRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -92,7 +93,7 @@ export function SharePage() {
|
|||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
generateWxacode({ width: 430 })
|
generateWxacode({ width: 430 })
|
||||||
.then((url) => {
|
.then((url) => {
|
||||||
if (!cancelled) setWxacodeUrl(url);
|
if (!cancelled) { wxacodeUrl.current = url; forceUpdate(n => n + 1); }
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.warn("[SharePage] 太阳码生成失败:", err);
|
console.warn("[SharePage] 太阳码生成失败:", err);
|
||||||
@@ -105,20 +106,20 @@ export function SharePage() {
|
|||||||
// 卸载时清理 blob URL
|
// 卸载时清理 blob URL
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
if (wxacodeUrl?.startsWith("blob:")) URL.revokeObjectURL(wxacodeUrl);
|
if (wxacodeUrl.current?.startsWith("blob:")) URL.revokeObjectURL(wxacodeUrl.current);
|
||||||
};
|
};
|
||||||
}, [wxacodeUrl]);
|
}, []);
|
||||||
|
|
||||||
// 生成长图
|
// 生成长图
|
||||||
const generateImage = useCallback(async (): Promise<string | null> => {
|
const generateImage = useCallback(async (): Promise<string | null> => {
|
||||||
if (!cardRef.current) return null;
|
if (!cardRef.current) return null;
|
||||||
|
|
||||||
// 等待太阳码渲染完成(blob URL 需浏览器解码)
|
// 等待太阳码渲染完成(blob URL 需浏览器解码)
|
||||||
if (shareData && !wxacodeUrl) {
|
if (shareData && !wxacodeUrl.current) {
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const tick = () => {
|
const tick = () => {
|
||||||
if (wxacodeUrl || Date.now() - start > 1500) {
|
if (wxacodeUrl.current || Date.now() - start > 1500) {
|
||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -126,7 +127,7 @@ export function SharePage() {
|
|||||||
};
|
};
|
||||||
tick();
|
tick();
|
||||||
});
|
});
|
||||||
if (!wxacodeUrl) {
|
if (!wxacodeUrl.current) {
|
||||||
console.warn("[SharePage] 太阳码未就绪,截图中可能缺失二维码");
|
console.warn("[SharePage] 太阳码未就绪,截图中可能缺失二维码");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,7 +148,7 @@ export function SharePage() {
|
|||||||
console.error("生成图片失败:", err);
|
console.error("生成图片失败:", err);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, [shareData, wxacodeUrl]);
|
}, [shareData]);
|
||||||
|
|
||||||
// 一键保存到相册 / 下载
|
// 一键保存到相册 / 下载
|
||||||
const handleSaveImage = useCallback(async () => {
|
const handleSaveImage = useCallback(async () => {
|
||||||
@@ -665,7 +666,7 @@ function ShareCardContent({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 太阳码区(截图包含) */}
|
{/* 太阳码区(截图包含) */}
|
||||||
{wxacodeUrl && (
|
{wxacodeUrl.current && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
@@ -674,7 +675,7 @@ function ShareCardContent({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={wxacodeUrl}
|
src={wxacodeUrl.current}
|
||||||
alt="扫码下载孕育无忧"
|
alt="扫码下载孕育无忧"
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ export default defineConfig(({ mode }) => {
|
|||||||
// File types to support raw imports. Never add .css, .tsx, or .ts files to this.
|
// File types to support raw imports. Never add .css, .tsx, or .ts files to this.
|
||||||
assetsInclude: ['**/*.svg', '**/*.csv'],
|
assetsInclude: ['**/*.svg', '**/*.csv'],
|
||||||
|
|
||||||
|
build: {
|
||||||
|
// 使用 esbuild 代替 terser 避免变量名 mangling 导致 ReferenceError
|
||||||
|
minify: 'esbuild',
|
||||||
|
},
|
||||||
|
|
||||||
server: {
|
server: {
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
allowedHosts: ['.trycloudflare.com', '.loca.lt'],
|
allowedHosts: ['.trycloudflare.com', '.loca.lt'],
|
||||||
|
|||||||
Reference in New Issue
Block a user