NextJS客户端组件调用Server Action时如何实现骨架屏加载?
客户端组件中实现Server Action加载状态与骨架屏
当然可以在客户端组件中实现骨架屏或加载状态,核心是通过管理加载状态来控制UI的切换,以下是针对你代码的具体实现方案:
1. 添加加载状态State
在组件中新增一个用于标记请求状态的State:
const [isLoading, setIsLoading] = React.useState(false);
2. 更新提交逻辑,控制加载状态
修改onSubmit函数,在请求开始前设置加载状态,请求结束(成功/失败)后重置状态:
async function onSubmit(data: z.infer<typeof FormSchema>) { setIsLoading(true); // 启动加载状态 try { const imageStringify = await requestImg(data); const binaryData = Buffer.from(imageStringify.image); const imageBase64 = URL.createObjectURL( new Blob([binaryData.buffer], { type: "image/jpeg" }) ); setOpen(true); setSource(imageBase64); } catch (error) { // 可选:添加错误处理逻辑,比如提示用户 console.error("图片生成失败:", error); } finally { setIsLoading(false); // 无论请求结果如何,结束加载状态 } }
3. 加载状态下的UI处理
根据isLoading状态,在UI中展示骨架屏或禁用交互:
方式1:修改提交按钮状态
避免用户重复提交,同时提供视觉反馈:
<button type="submit" className="..." disabled={isLoading} > {isLoading ? "生成中..." : "生成图片"} </button>
方式2:图片区域显示骨架屏
当弹窗打开但请求未完成时,用骨架屏替代图片:
{open && ( <div className="modal"> {isLoading ? ( {/* 骨架屏示例,可根据实际布局调整尺寸和样式 */} <div className="w-full h-[400px] bg-gray-200 rounded animate-pulse"></div> ) : ( <img src={source} alt="生成的图片" className="w-full h-auto" /> )} </div> )}
关键注意事项
- 必须在
await requestImg(data)之前调用setIsLoading(true),确保React及时更新UI,避免用户误以为页面阻塞。 - 使用
finally块重置加载状态,防止请求失败后加载状态一直停留。 - 骨架屏的样式可以根据你的UI设计调整,比如使用渐变动画、匹配图片的宽高比等,提升用户体验。
内容的提问来源于stack exchange,提问作者NicoCaldo
相关产品推荐
相关产品推荐

