You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Inertia React中preserveState不生效,页面重载丢失状态

解决Inertia请求后状态重置的问题

1. 用函数式更新状态规避闭包陷阱

你当前的setAllProducts依赖作用域内的allProducts变量,这会导致闭包捕获旧状态值,当Inertia请求完成时,无法获取最新的状态快照。改成函数式更新即可解决:

const fetchProducts = (page) => {
    Inertia.get(
      `/products?page=${page}`,
      { filters },
      {
        preserveState: true,
        preserveScroll: true,
        only: ['products'],
        onSuccess: (response) => {
          // 通过函数式更新获取最新的前序状态
          setAllProducts(prev => prev.concat(response.props.products.data));
        }
      }
    )
};

2. 将分页页码纳入状态管理

你在onSuccess中修改的page是局部参数,下次调用fetchProducts时仍会传入旧值。应该把页码用useState统一管理:

const [currentPage, setCurrentPage] = useState(1);

const fetchProducts = () => {
    Inertia.get(
      `/products?page=${currentPage}`,
      { filters },
      {
        preserveState: true,
        preserveScroll: true,
        only: ['products'],
        onSuccess: (response) => {
          setAllProducts(prev => prev.concat(response.props.products.data));
          setCurrentPage(prev => prev + 1);
        }
      }
    )
};

3. 确认组件未被重复挂载

preserveState: true仅在同一页面组件的导航场景下生效,如果路由配置导致页面组件被卸载后重新挂载(比如路由路径变化但对应组件未复用、嵌套路由层级变更),状态会被强制重置。可以通过以下代码排查组件挂载情况:

useEffect(() => {
  console.log('组件已挂载');
  return () => console.log('组件已卸载');
}, []);

若确实存在重复挂载,可采取两种方案:

  • 检查Inertia路由配置,确保分页导航指向同一个页面组件
  • 将filters和allProducts存入本地存储,在组件初始化时恢复:
const [filters, setFilters] = useState(() => {
  const saved = localStorage.getItem('productFilters');
  return saved ? JSON.parse(saved) : [];
});

const [allProducts, setAllProducts] = useState(() => {
  const saved = localStorage.getItem('allProducts');
  return saved ? JSON.parse(saved) : [];
});

// 监听filters变化并持久化
useEffect(() => {
  localStorage.setItem('productFilters', JSON.stringify(filters));
}, [filters]);

// 按需持久化allProducts
useEffect(() => {
  localStorage.setItem('allProducts', JSON.stringify(allProducts));
}, [allProducts]);

4. 验证请求目标页面的一致性

确保/products?page=${page}对应的后端路由返回的是同一个Inertia页面组件。如果后端渲染了不同的组件,前端状态会被直接重置。

内容的提问来源于stack exchange,提问作者Jenssen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:36:32