NextJS13客户端组件输入时反复触发loading.jsx加载问题求助
问题原因与解决方案
核心问题:客户端组件被错误定义为异步函数
在Next.js 13的App Router中,标记了'use client'的客户端组件不能是异步(async)函数。你把Books组件写成了async () => {},这会让Next.js误判它为需要加载服务器数据的组件——每次组件因状态变化(比如输入框onChange修改query)重新渲染时,都会触发路由级别的loading.jsx,因为框架认为这个"异步组件"正在加载服务器数据。
修复步骤
- 移除组件的async关键字:客户端组件必须是普通同步函数。
- 修正loading状态逻辑:初始状态设为
true,确保数据加载完成前显示自定义loading(如果需要)。
修正后的Books组件代码
'use client'; import { useState, useEffect } from "react"; import Link from "next/link"; import LoadingPage from "../loading"; async function getBooks() { const res = await fetch("http://localhost:3000/api/books"); const json = await res.json(); return json; } // 移除async关键字,改为普通函数 const Books = () => { const [books, setBooks] = useState([]); // 初始loading设为true,确保数据加载时显示状态 const [loading, setLoading] = useState(true); const [query, setQuery] = useState(""); useEffect(() => { getBooks().then((books) => { setBooks(books); setLoading(false); }).catch(() => { setLoading(false); }); },[]); // 可以根据loading状态显示自定义loading组件,而非路由级的loading.jsx if(loading){ return <LoadingPage /> } const handleSubmit = async (e) => { e.preventDefault(); console.log(query); // 后续搜索逻辑可以在这里补充 } return ( <div> <form onSubmit={handleSubmit}> <input type="text" placeholder="Search Books..." value={query} onChange={(e) => setQuery(e.target.value)} className="input input-bordered w-full max-w-xs" /> <button type="submit" className="btn btn-primary">Search</button> </form> {books.map((book) => ( <div key={book.id}> <div className="card w-96 bg-base-100 shadow-xl"> <figure> <img src={book.img} width="200" height="150" alt={book.title} /> </figure> <div className="card-body"> <h2 className="card-title">{book.id}</h2> <p>{book.title}</p> <div className="card-actions justify-end"> <Link href={book.link} className="btn btn-primary">See in Amazon</Link> </div> </div> </div> <br /> </div> ))} </div> ) } export default Books;
补充说明
- App Router中的
loading.jsx是路由段级别的加载组件,仅在路由导航、服务器组件加载数据时触发,客户端组件的本地状态变化(比如输入框输入)本不该触发它。 - 客户端组件内的异步逻辑(比如数据获取)必须放在
useEffect或其他客户端生命周期钩子中,不能直接把组件定义为async函数。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

