React Hydration Logic Challenge
This challenge focuses on implementing server-side rendering (SSR) hydration in a React application. You will create a simple component that renders data fetched on the server and ensure it correctly hydrates on the client, preventing mismatches and providing a seamless user experience. This is crucial for performance and SEO in modern web applications.
Problem Description
Your task is to build a React component that displays a list of user profiles. This data will initially be rendered on the server and then "hydrated" on the client. You need to ensure that the client-side React application correctly reuses the server-rendered HTML without re-rendering components, which is the core principle of hydration.
Key Requirements:
- Server-Side Rendering (SSR) of Data: Assume that user data is available to the server during SSR. This data will be embedded in the initial HTML response.
- Client-Side Hydration: The React application running in the browser should detect the server-rendered HTML and attach event listeners and manage state without re-rendering the DOM.
- Component Structure: Create a
UserProfileListcomponent that accepts an array of user objects as props. Each user object will have at least anidand aname. - Display User Names: The
UserProfileListcomponent should render an unordered list (<ul>) where each list item (<li>) displays a user's name. - No Client-Side Fetching (for this challenge): For the purpose of this challenge, assume the data is already available to the client through the initial SSR payload. You do not need to implement client-side data fetching logic.
Expected Behavior:
- When the page loads, the user profile names should be immediately visible (from SSR).
- The client-side React application should successfully "hydrate" these elements. If hydration fails (e.g., due to a mismatch), React will typically warn in the console. Your goal is to avoid these warnings.
- The rendered HTML should be consistent between the server and the client.
Edge Cases:
- Empty User List: The component should gracefully handle cases where the
usersprop is an empty array ornull/undefined.
Examples
Example 1:
// Server-side data passed to the component
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
];
// Expected HTML rendered by the server
// (Simplified, actual HTML will have React attributes)
`
<ul>
<li>Alice</li>
<li>Bob</li>
</ul>
`
Example 2:
// Server-side data passed to the component
const users = [];
// Expected HTML rendered by the server
`
<ul></ul>
`
Example 3:
// Server-side data passed to the component
const users = null;
// Expected HTML rendered by the server
`
<ul></ul>
`
Constraints
- Language: TypeScript
- Framework: React (with a hypothetical SSR setup)
- Data Structure: User objects will have
id: numberandname: string. - Performance: The hydration process should be efficient. Avoid unnecessary re-renders.
Notes
- This challenge simulates a common SSR scenario. In a real application, you would use a framework like Next.js or Remix, or configure your own SSR setup with libraries like
react-dom/serverandreact-dom/client. - The core of this challenge is to demonstrate how React's
createRoot(container).hydrate(element)(or the olderReactDOM.hydrate) works with SSR-rendered content. - Pay attention to how you pass the initial data from the server to the client. Common methods include embedding it in a
<script>tag as JSON or using specific data attributes. For this challenge, focus on the React component's ability to consume that data and the hydration process itself. - Your primary goal is to write a React component that is SSR-friendly and demonstrates correct hydration. The SSR setup itself is abstracted away.