我在用骨架屏优化列表页加载体验,但数据回来后会先闪一下空白再显示内容,体验很割裂。明明骨架屏和真实结构样式一致,不知道是不是 setState 的时机问题?
我试过在 useEffect 里请求数据,也加了 loading 状态控制,但还是有闪屏。代码大概这样:
useEffect(() => {
setLoading(true);
fetchData().then(res => {
setData(res);
setLoading(false); // 这里切换后会闪一下
});
}, []);
试试这个方案:保持 loading 状态到数据完全准备好再切换。可以在 setData 前预处理数据结构,确保数据格式完整后再触发渲染。
这样能保证骨架屏和真实数据之间过渡更平滑。记得检查 CSS 样式是否一致,有时候样式差异也会导致视觉上的闪动。如果还有问题,考虑用 css transition 来平滑过渡效果。
先说最直接的解决方案:不要让 loading 状态直接控制显示隐藏,用 CSS 过渡来平滑切换。
你的代码稍微改一下:
对应的 CSS:
另外还有个容易忽略的点:你的骨架屏和真实内容的 DOM 结构要完全一致,包括高度。很多时候闪屏是因为骨架屏占位是固定高度,但真实内容渲染后发现高度变了,页面会跳一下。
如果用的是同一个组件,可以通过条件渲染不同的 children 来解决:
最后提醒一下,setTimeout 的 50ms 可以根据实际效果调整,太短了过渡会显得突兀,太长了又会让用户觉得慢。如果接口响应本身比较快,这个时间可以设得更短或者不加。