Troubleshooting React Issues When Transitioning Between Pages

We’ve encountered a peculiar issue where some components break when navigating between pages using a link. This article will walk you through the problem and its solution, particularly when reading properties from the context page instead of the data source item.

The Issue

If your component works fine when loading a page directly via the URL but encounters null issues when accessing it through a link, this guide will help you troubleshoot the problem.

Before diving into the sample case, it’s important to understand that transitioning between pages happens on the client side, similar to how a Single Page Application (SPA) behaves.

Sample Case

Consider a scenario where Page A contains a list of links, and clicking on one of these links navigates to Page B. Page B includes a component that reads fields from the Context Page.

However, after clicking the link to navigate to Page B, the page breaks due to a null error. But why?

Debugging the Issue

All fields on Page B are required, so a null value was unexpected. To investigate, I attached a debugger and found that the Navigation Title still referred to Page A instead of Page B.

Root Cause Analysis

Reviewing the code, I noticed that the component was being called from the origin page (Page A), meaning field.careerListingSource was undefined because it didn’t exist in that context.

The Solution

The fix was straightforward: add a null check on the property, considering the scenario where that field doesn’t exist on the origin page.

After implementing this change, the page loaded successfully because:

  1. First Load: The CareerList component was initially loaded in the origin page (Page A), but the execution was handled gracefully even if the component wasn’t presented.
  2. Second Execution: The CareerList component was loaded correctly in the target page (Page B), as expected.

Conclusion

When working with components that rely on fields from the Context Page, remember that your component might be rendered on a page where those fields don’t exist. Adding proper null checks or fallback values will prevent your component from breaking during transitions.

I hope this article saves you time troubleshooting similar issues!

Relevant Documentation:
Routing: Linking and Navigating

Read more

Passing Attributes between Components within Placeholders in XM Cloud [NextJS]

Hey there! Have you ever found yourself scratching your head, wondering how to smoothly pass attributes from one component to another nestled inside Sitecore Placeholders? I recently delved into this topic, exploring the documentation provided by Sitecore (check it out here).

Despite diving into the docs, I couldn’t find a straightforward way to achieve this task. But fear not! I stumbled upon a hidden gem within the placeholder — the modifyComponentProps function.

 /**
     * Modify final props of component (before render) provided by rendering data.
     * Can be used in case when you need to insert additional data into the component.
     * @param {ComponentProps} componentProps component props to be modified
     * @returns {ComponentProps} modified or initial props
     */
 modifyComponentProps?: (componentProps: ComponentProps) => ComponentProps;

Excitedly, I decided to give it a whirl. However, to my dismay, it seemed like nothing happened, at least not with JSS v21.6.0.

After some pondering, I speculated that the ComponentPropsFactory might be overriding modifyComponentProps. But lo and behold, I found the information tucked away in ComponentPropsContext. And thus, a solution was born — a function to help you effortlessly achieve your goal.

All you need to do is install the following library:

npm i @constellation4sitecore/foundation-enhancers

Let me walk you through an example. Say you want to send properties to a child component inserted into a Placeholder.

const MyComponent = ({ fields, params, rendering }: MyComponentProps) => {
    // Invoke the magic
  useModifyChildrenProps(rendering, {
    myProp1: fields.myProp1,
    myProp2: 'hello world!',
  });

  return (
    <Placeholder
      name={`my-chindren-modules-${params.DynamicPlaceholderId}`}
      rendering={rendering}
    />
  );
};

And in your Children Component, you can effortlessly retrieve all the passed data.

type ChildComponentProps = {
    fields: Fields,
    // Add prop types here
    myProp1: Field<string>
    myProp2: string
}
const ChildComponent = ({ myProp1, myProp2 }: ChildComponentProps) => (
  <>
    <Text field={myProp1} />
    <span>{myProp2}</span>
  </>
);

This nifty solution has made passing data to all children a breeze. I hope you find this information as helpful as I did!

Common use cases:

  • You have a Tab component and need to send the active ID to children.
  • You need to re-render some props on specific breakpoints in the children component (e.g., mobile, desktop), and the parent component holds the information.

If you’re curious to dive deeper into this functionality and perhaps even contribute, you’re in luck! The function we discussed is part of an open-source project called Constellation 4 Sitecore. You can find the source code and contribute your ideas and improvements on Check it on Github!. We welcome collaboration from developers of all levels of expertise. Let’s join forces and make this tool even more powerful together! 🚀

Special thanks to Josue Jaramillo for invaluable assistance in troubleshooting the issue!

Read more