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

Inertia.post请求后usePage().props未更新的原因排查

问题

我有一个用户搜索组件,Laravel控制器代码如下:

public function find(Request $request): RedirectResponse
{
    $identifier = trim($request->input('identifier'));

    $id = $this->simpleUserSearch->find($identifier);

    if (empty($id)) {
        session()->flash('error', 'No logs for this user found, sorry!');
        return redirect()->route('dashboard.users.index');
    }

    return redirect()->route('dashboard.users.show', ['user' => $id]);
}

在HandleInertiaRequests中间件中,我按如下方式存储session错误:

public function share(Request $request): array
{
    $isAdmin = Auth::user() instanceof Admin;
    return array_merge(parent::share($request), [
        'csrf' => csrf_token(),
        'session' => [
            'notification' => session('notification'),
            'error' => session('error'),
        ],
        'auth' => self::share_auth(Auth::user()),
    ]);
}

前端组件中,我使用以下方法触发搜索请求:

function search() {
  Inertia.post('/dashboard/users/find', {identifier: key.value})
  console.log(usePage().props.value.session.error);
  error.value = usePage().props.value.session.error;
}

搜索失败时,usePage().props.value.session.error仍为null,但通过VueInspector可见它应存在值;再次发起请求时,该值才会被赋值为上一次的错误。请问为何第一次请求时未完成赋值?

原因分析

这是因为Inertia请求是异步的:调用Inertia.post()后立刻读取usePage().props,此时后端响应还未返回,页面props仍是请求发起前的旧值,所以读取到null。

VueInspector能看到错误值,是因为异步请求完成后Inertia已更新页面props;第二次请求时,上一次的flash session错误还未被清除,所以能读取到旧值。

另外,Laravel的session()->flash()是一次性存储,仅在下一次请求周期内有效,这也和你遇到的现象完全吻合:第一次请求触发flash,redirect后的页面会携带该错误,但同步代码中无法即时获取。

解决方案

方法1:利用Inertia请求的回调函数

Inertia的请求方法支持回调,在请求成功完成后再读取更新后的props:

function search() {
  Inertia.post('/dashboard/users/find', {identifier: key.value}, {
    onSuccess: () => {
      error.value = usePage().props.value.session.error;
      console.log(error.value);
    }
  })
}

方法2:监听页面props变化

在Vue组件中通过watch监听usePage().props的变化,自动更新error值:

import { watch, ref } from 'vue';
import { usePage } from '@inertiajs/vue3';

const page = usePage();
const error = ref(null);

// 监听session.error的变化,即时更新
watch(() => page.props.value.session.error, (newError) => {
  error.value = newError;
}, { immediate: true }); // immediate: true 确保组件初始化时也能读取当前值

function search() {
  Inertia.post('/dashboard/users/find', {identifier: key.value});
}

可选优化:调整后端跳转逻辑

如果不需要跳转到用户列表页,可改用back()返回原页面,避免额外的路由跳转,让Inertia直接更新当前页面的props:

public function find(Request $request)
{
    $identifier = trim($request->input('identifier'));

    $id = $this->simpleUserSearch->find($identifier);

    if (empty($id)) {
        return back()->with('error', 'No logs for this user found, sorry!');
    }

    return redirect()->route('dashboard.users.show', ['user' => $id]);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:00:23