InertiaJS router.get带参数无法保留状态,整页刷新及搜索功能实现咨询
InertiaJS React 搜索筛选状态保留失效(整页刷新)问题解决方案
常见错误原因及解决方法
1. 误用原生表单/链接触发整页刷新
如果搜索输入包裹在原生<form>标签中,或使用普通<a>标签,浏览器会触发默认导航行为,直接整页刷新,完全绕过Inertia的状态保留机制。
解决:
- 若使用表单,必须在提交事件中调用
e.preventDefault()阻止默认行为,再用Inertia router发起请求:
const handleSubmit = (e) => { e.preventDefault(); router.get('/users', { search }, { preserveState: true }); }; // 对应表单 <form onSubmit={handleSubmit}> <input type="text" value={search} onChange={(e) => setSearch(e.target.value)} /> <button type="submit">搜索</button> </form>
- 避免用普通
<a>标签触发搜索,统一使用Inertia的router方法。
2. 未正确使用Inertia Router实例
确保导入并使用Inertia提供的router对象,而非原生window.location或其他路由工具,后者会直接触发整页刷新。
正确示例:
import { router } from '@inertiajs/react'; const handleSearchChange = (e) => { const newSearch = e.target.value; setSearch(newSearch); // 用Inertia router发起请求,开启状态保留 router.get('/users', { search: newSearch }, { preserveState: true, preserveScroll: true, // 可选:保留页面滚动位置 }); };
3. 后端未返回Inertia格式响应
如果后端路由返回普通HTML页面而非Inertia组件响应,Inertia无法识别,进而触发整页刷新。
后端示例(以Laravel为例):
use Inertia\Inertia; use Illuminate\Http\Request; Route::get('/users', function (Request $request) { // 根据搜索条件过滤数据 $users = \App\Models\User::when($request->search, function ($query) use ($request) { $query->where('name', 'like', "%{$request->search}%"); })->get(); // 返回Inertia组件响应 return Inertia::render('Users/Index', [ 'users' => $users, ]); });
4. 排查其他触发整页刷新的代码
检查项目中是否存在主动触发整页刷新的代码,比如window.location.reload()、window.location.href = ...等,这些操作会直接覆盖Inertia的状态保留逻辑。
完整实现示例
import { useState } from 'react'; import { router } from '@inertiajs/react'; function UserTable({ users }) { const [search, setSearch] = useState(''); // 实时搜索(可添加防抖优化频繁请求) const handleSearchChange = (e) => { const newSearch = e.target.value; setSearch(newSearch); router.get('/users', { search: newSearch }, { preserveState: true, preserveScroll: true, }); }; return ( <div className="p-4"> <input type="text" className="mb-4 p-2 border rounded" value={search} onChange={handleSearchChange} placeholder="输入用户名搜索..." /> {/* 数据表格渲染 */} <table className="border-collapse w-full"> <thead> <tr> <th className="border p-2">ID</th> <th className="border p-2">用户名</th> </tr> </thead> <tbody> {users.map(user => ( <tr key={user.id}> <td className="border p-2">{user.id}</td> <td className="border p-2">{user.name}</td> </tr> ))} </tbody> </table> </div> ); } export default UserTable;
内容的提问来源于stack exchange,提问作者andcl
相关产品推荐
相关产品推荐

