Frontend - React
Goal
The goal of the frontend React live coding interview is to evaluate the candidate's ability to design and implement interactive, maintainable user interfaces using React. This includes assessing their problem-solving skills, understanding of React concepts and best practices, and ability to write clean, efficient code under time constraints.
Check general recommendations for Live Codings Interviews.
React Concepts
Data fetching
Compared to a solution using React Query or other framework:
- Parallelization: Cleanup functions
- State handling
- Caching
Data display
- Special props: Why React needs a key prop
Filtering
- Managed and derived states: Don't sync state, derive it!
UX
Optimistic updates
We do it for responsiveness!
In practice, when a user interacts with an application—such as submitting a form or liking a post—the frontend immediately updates the UI to reflect the expected outcome of that action. In summary, optimistic updates enhance user experience by making applications feel faster and more interactive.
Pagination and infinite scrolling
The choice between pagination and infinite scrolling largely depends on the nature of the content and the goals of the application. For data-heavy applications where users may need to find specific items quickly (such as tables or search results just selecting a page number), pagination may be more effective. In contrast, for content-centric applications (like social media feeds or image galleries), infinite scrolling can create a more engaging and enjoyable experience.
Additional questions
- Debounce: What is it and when you should use it?
- Skeleton vs loading spinner:
- Quick operations: Spinner. Also for situations where immediate feedback is needed without complex content layout like background operations.
- Large operations: Skeleton because it gives the user a sense of the layout and what to expect and an improvement into the perceived performance.
Performance
Memoization
Calculations performed within render will be performed every single render, regardless of whether the inputs for the calculations change.
function Distance({ x, y }) {
const distance = calculateDistance(x, y);
return (
<div>
The distance between {x} and {y} is {distance}.
</div>
);
}
If that component's parent re-renders, or if we add some unrelated state to the component and trigger a re-render, we'll be calling calculateDistance
every render which could lead to a performance bottleneck
Solution:
const distance = React.useMemo(() => calculateDistance(x, y), [x, y]);
Lists virtualization
Unfortunately, there's not much React can do if you simply need to make huge updates to the DOM. And as fast as React is in the reconciliation phase, if it has to do that for tens of thousands of elements that's going to take some time ("perf death by a thousand cuts"). In addition, our own code that runs during the "render" phase may be fast, but if you have to do that tens of thousands of times, you're going to have a hard time being fast on low-end devices.
But here's the trick. Often you don't need to actually display tens of thousands of list items, table cells, or data points to users. So if that content isn't displayed, then you can kinda cheat by doing some "lazy" just-in-time rendering.
So let's say you had a grid of data that rendered 100 columns and had 5000 rows. Do you really need to render all 500000 cells for the user all at once? They certainly won't see or be able to interact with all of that information at once. You'll only display a "window" of 10 columns by 20 rows (so 200 cells for example), and the rest you can delay rendering until the user starts scrolling around the grid.
Maybe you can render a few cells outside the view just in case they're a really fast scroller. In any case, you'll save yourself a LOT of computational power by doing this "lazy" just-in-time rendering.
This is a concept called "windowing" and in some cases it can really speed up your components that render lots of data