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

WordPress页面间postMessage传递React数据出现旧数据问题求助

问题分析

核心问题是页面跳转时,postMessage的发送时机与结果页App.js的加载时机不匹配:点击搜索后,FrontPage.js在当前页面发送postMessage,但此时结果页还未初始化,App.js的message事件监听还未注册,因此无法接收到本次的最新消息,反而可能读取到之前会话遗留的旧数据。而你已经确认localStorage中存储的是最新数据,说明存储环节没问题,问题出在消息传递或数据读取的时机上。

解决方案

方案1:放弃postMessage,结果页主动读取localStorage(最直接)

既然localStorage已经存储了正确的最新数据,完全可以让App.js在初始化时主动读取localStorage,而不是依赖不可靠的postMessage。

修改App.js代码:

import { useEffect } from 'react';

// 在组件初始化时读取localStorage
useEffect(() => {
  const storedData = localStorage.getItem('flightCardsDataArray');
  if (storedData) {
    const latestData = JSON.parse(storedData);
    console.log('flightCardsDataArray - from localStorage', latestData);
    // 这里将数据设置到组件状态中,比如 setFlightData(latestData)
  }
  // 可选:读取后清空localStorage,避免下次加载时读取到旧数据
  localStorage.removeItem('flightCardsDataArray');
}, []);

// 保留原有的message监听(可选,兼容其他场景)
window.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'flightCardsDataLoaded') {
    const data = event.data.data;
    console.log('flightCardsDataArray - from message', data);
    // 更新组件状态
  }
});

同时,FrontPage.js可以保留localStorage的操作,移除不必要的postMessage:

localStorage.clear();
localStorage.setItem('flightCardsDataArray', JSON.stringify(flightCardsDataArray));
isDataLoaded();
// 移除window.postMessage这一行

方案2:调整postMessage发送时机,确保结果页已加载

如果必须使用postMessage,可以通过延迟跳转或让结果页主动请求数据的方式,确保消息能被正确接收。

实现方式:结果页加载后主动请求数据

  1. FrontPage.js点击搜索时,先存储数据,再打开结果页并监听请求:
localStorage.clear();
localStorage.setItem('flightCardsDataArray', JSON.stringify(flightCardsDataArray));
isDataLoaded();

// 打开结果页窗口
const resultWindow = window.open('/result-page');
// 轮询检查结果页是否加载完成
const checkLoaded = setInterval(() => {
  if (resultWindow?.readyState === 'complete') {
    resultWindow.postMessage({ type: 'flightCardsDataLoaded', data: flightCardsDataArray }, '*');
    clearInterval(checkLoaded);
  }
}, 100);
  1. App.js初始化时监听消息:
import { useEffect } from 'react';

useEffect(() => {
  const handleMessage = (event) => {
    if (event.data && event.data.type === 'flightCardsDataLoaded') {
      const latestData = event.data.data;
      console.log('flightCardsDataArray - from parent', latestData);
      // 更新组件状态
    }
  };
  window.addEventListener('message', handleMessage);
  // 组件卸载时移除监听
  return () => window.removeEventListener('message', handleMessage);
}, []);

这种方式需注意窗口引用和同域限制,相对复杂,仅适合必须使用postMessage的场景。

方案3:使用URL传递搜索参数(更符合页面跳转逻辑)

如果flightCardsDataArray是基于搜索参数生成的,可以直接将关键搜索参数通过URL传递到结果页,App.js根据参数重新获取数据,避免前端存储带来的旧数据问题。

实现方式:

  1. FrontPage.js跳转时携带参数:
// 假设搜索参数为query、date等
const searchParams = new URLSearchParams({
  query: '北京到上海',
  date: '2024-05-20'
});
window.location.href = `/result-page?${searchParams.toString()}`;
  1. App.js读取URL参数并请求数据:
import { useEffect } from 'react';

useEffect(() => {
  const params = new URLSearchParams(window.location.search);
  const query = params.get('query');
  const date = params.get('date');
  // 根据参数调用后端接口获取最新数据
  fetch(`/api/flights?query=${query}&date=${date}`)
    .then(res => res.json())
    .then(data => {
      console.log('flightCardsDataArray - from API', data);
      // 更新组件状态
    });
}, []);

这种方式符合HTTP无状态特性,利于SEO,也避免了前端存储的潜在问题。

总结

优先推荐方案1,代码改动最小且可靠,利用已确认正确的localStorage数据直接读取;如果数据敏感或不适合前端存储,推荐方案3,通过URL参数+后端接口获取数据,更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:16:30