javascriptreactjswordpresswindow-object

Inserting react code based on postMessage between two wordpress pages


In wordpress I am clicking a search button in front-page.php , that calls a result page . front-page.php loads FrontPage.js , which has this:

  localStorage.clear();
  localStorage.setItem('flightCardsDataArray', JSON.stringify(flightCardsDataArray));
  isDataLoaded();
  window.postMessage({ type: 'flightCardsDataLoaded', data: flightCardsDataArray }, '*');

I would like to read this message in App.js , which is React code and this react code insert cards on result page . In App.js I am doing this

window.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'flightCardsDataLoaded') {
    // Data has been sent from the search page
    const data = event.data.data;
    console.log('flightCardsDataArray - from app', data);
  }
});

but it always gives me data , which is associated with the previous search. I would like to get data for the current search (latest click on search button of front-page.php) .

UPDATE As per suggestion below , I set the debugger and see that correct iteration of data is passed in flightCardsDataArray when I set it in localstorage, however I am still not able to figure out why App.js shows previously passed data.

My guess is that App.js is reading the message even before the latest click happens , but how do I resolve this? Or is there any other way to approach this?


Solution

  • I changed the approach and made the API call in React itself. So , when the button is clicked in front-page.php , it goes to result page.php which is rendered by React . So I made the call to API in React just before rendering hence eliminating the need for event listeners to listen from one page to another to transfer data.

    The data that needs to be passed from front-page.php to result page.php and do not require event listeners can still be passed using localStorage.setItem and get it in react using localStorage.getItem . Here is what I am doing in react application which includes fetching and parsing data

    const CreateApp = (props) => {
    
      //use useState (https://react.dev/reference/react/useState) for handling asynchronous behavior
    
      const [card, setCard] = useState([]);
      const [cardLoaded, setCardLoaded] = useState(false);
      const fetchCardData = async () => {
        try {
       
          const options = {
            method: 'GET',
            url: 'https://yourapi.com/method',
            params: {
              param1: '1',
              param2: localStorage.getItem('param2'),
              param3: localStorage.getItem('param3'),
            },
            headers: {
              'content-type': 'application/octet-stream',
              'Some-Key': 'abc',
              'Some-Host': 'yourapi.com'
            }
          };
    
             const response = await axios.request(options);
             
           //parse response
            return parsedResponse ;
        } catch (error) {
    
          console.error('Error occurred while parsing , error);
          return { success: false };
        }
      }
    
     //useEffect for rendering with asynchronous response (https://react.dev/reference/react/useEffect#useeffect)
    
      useEffect(() => {
         // Call the fetchCardData function to fetch data
         fetchCardData()
           .then((parsedResponse) => {
              
             // Now you have the parsedResponse, you can set it in your state or use it as needed
             setCard(parsedResponse);
             setCardLoaded(true);
           })
           .catch((error) => {
             console.error('Error occurred while fetching data:', error);
           });
       }, []);
    
    
    if (!cardLoaded) {
      return <p>Loading...</p>;
    }
      //render with data
      const columns = card.map((item, index) => {
     return(
     <div className="col-lg-4 responsive-column">
      ....
      .... 
     </div>
        );
     });
         
    return <>{columns}</>;
    
    }
    export default CreateApp;