Laravel9+React18组件console.log重复输出及Inertia函数疑问
</> );
}
执行`npm run build`构建生产环境,通过`php artisan serve`启动本地服务后,在Chrome开发者工具中发现`console.log`内容输出两次。 ### 疑问点 1. 根据React官方文档,开发模式下Strict Mode会导致组件两次渲染,但生产环境下仍出现重复输出,希望了解原因。 2. 使用Profiler排查后发现,首次渲染后触发了“Inertia state update scheduled”导致二次渲染,该操作由函数L执行,想了解该函数的具体作用: ```jsx function L({ children: l, initialPage: c, initialComponent: a, resolveComponent: p, titleCallback: s, onHeadUpdate: S2 }) { let [d, P] = (0, import_react2.useState)({ component: a || null, page: c, key: null }), u2 = (0, import_react2.useMemo)(() => Q(typeof window > "u", s || ((f2) => f2), S2 || (() => { })), []); if ((0, import_react2.useEffect)(() => { Oe.init({ initialPage: c, resolveComponent: p, swapComponent: async ({ component: f2, page: e, preserveState: i }) => { P((r) => ({ component: f2, page: e, key: i ? r.key : Date.now() })); } }), Oe.on("navigate", () => u2.forceUpdate()); }, []), !d.component) return (0, import_react2.createElement)(A2.Provider, { value: u2 }, (0, import_react2.createElement)(E.Provider, { value: d.page }, null)); let g = l || (({ Component: f2, props: e, key: i }) => { let r = (0, import_react2.createElement)(f2, { key: i, ...e }); return typeof f2.layout == "function" ? f2.layout(r) : Array.isArray(f2.layout) ? f2.layout.concat(r).reverse().reduce((y, T) => (0, import_react2.createElement)(T, { children: y, ...e })) : r; }); return (0, import_react2.createElement)(A2.Provider, { value: u2 }, (0, import_react2.createElement)(E.Provider, { value: d.page }, g({ Component: d.component, key: d.key, props: d.page.props }))); }
解答
1. 生产环境下组件二次渲染的原因
这是Inertia.js初始化流程的正常行为,和Strict Mode无关:
- 首次渲染:根组件(函数L)会先用传入的
initialPage和initialComponent渲染初始页面,此时Welcome组件执行一次console.log。 - 二次渲染:根组件的
useEffect中会初始化Inertia实例,初始化时会触发swapComponent回调更新状态(即使是初始页面),触发根组件重新渲染,进而导致Welcome组件二次执行渲染逻辑。
这个流程在生产环境不会被跳过,因此会出现两次console.log输出。
2. 函数L的作用
这个函数是Inertia.js React适配器中根组件(InertiaApp)编译压缩后的代码,核心功能如下:
- 状态管理:通过
useState维护当前页面的组件实例、页面数据和唯一key(key用于控制组件是否重新挂载)。 - Inertia初始化与事件监听:在
useEffect中初始化Inertia实例,注册页面切换时的swapComponent回调(用于更新页面状态),同时监听navigate事件强制更新上下文。 - 上下文提供:通过两个Provider(对应Inertia核心上下文和页面数据上下文),将Inertia功能和当前页面数据传递给所有子组件。
- 布局渲染处理:自动解析页面组件的
layout属性,支持函数式布局、数组式嵌套布局,无布局则直接渲染页面组件。 - 页面切换状态控制:通过
key属性控制页面组件生命周期,preserveState为false时生成新key强制组件重新挂载;为true时复用旧key保留组件状态。
内容的提问来源于stack exchange,提问作者下谷勇気
相关产品推荐
相关产品推荐

