In September 2024, I’ve been able to join
Accessible CSS Layouts
During this talk, I was inspired to test the UIs I had built based on specific accessibility requirements. My main knowledge of accessibility (a11y) revolves around supporting people with visual impairments. However, I discovered that I had overlooked other aspects, such as
This talk taught me not only to use ‘rem’ sizes instead of pixels but also to consider how
clamp()
function, and how to effectively handle overflows with containers.All of these concepts were things I had implemented before but always with JavaScript. This talk demonstrated the power of CSS and how many of these issues can be solved solely through CSS.
Server Components & Actions
One of the most covered topics at the conference was
Interestingly, this blog you're reading is built with the Next.js App Router, where I use React Server Components. The talks reinforced my confidence in the stack and validated that I was using it correctly.
I really like how server and client-side components challenge developers to
Let’s look into a small example of what is possible with the stack:
'use client';
import Button from '@/components/ui/Button';
import type { PropsWithChildren } from 'react';
export default function ClientComponent({ children }: PropsWithChildren) {
return <Button theme="ghost">{children}</Button>;
}
Here you’ll see a basic example of a ClientComponent which specifies ‘use client’ on top. This tells the React compiler to render the component client-side. If this directive isn’t present, the compiler will render it server-side by default.
Next, we’ll create a server component:
import { prisma } from '@/db';
export default async function ServerComponent() {
const data = await prisma.contact.findMany();
return (
<div className="block rounded bg-gradient-to-tr from-purple-700 to-red-400 p-3 font-bold text-white shadow-md">
{data[0].first + ' - ' + data[0].email}
</div>
);
}
In here, you’ll see that the component has direct access to the database (prisma, ORM for database). This is super cool, as it enables us to directly call backend services in a secure way - since it’s executed
Now the cool part - in my opinion:
import ClientComponent from './_components/ClientComponent';
import ServerComponent from './_components/ServerComponent';
export default function ClientServerPage() {
return (
<ClientComponent>
<ServerComponent />
</ClientComponent>
);
}
Because the compiler knows how to render which component, we can nest different render strategies into each other. As example, a ClientComponent which renders the ServerComponent as a children.
The React Compiler efficiently handles this mixing of server and client components through a process called "
On the client side, React "hydrates" the static HTML by attaching event listeners and making it interactive. For client components, this process is straightforward. However, for server components nested within client components, React uses a technique called "selective hydration". This means it only hydrates the parts of the component tree that are actually client components, leaving the server-rendered parts as is.
This approach allows for optimal performance, as it minimizes the amount of JavaScript that needs to be sent to the client and reduces the time to be interactive. It's a clever way of combining the benefits of server-side rendering (faster initial load, better SEO) with the interactivity of client-side rendering, all while keeping the developer experience smooth and intuitive.
Finding & Fixing race conditions
This talk dove into the concept of asynchronous calls where execution order can vary, potentially leading to unexpected UI behavior or "jumps."
For example, let’s say a user is typing in a search bar. They first type
Since the backend is handling two asynchronous calls, it’s possible that the first query ("Men") might take longer because it returns more results, while the more specific "Men clothes" query resolves faster. If the "Men clothes" query resolves first, React will re-render with its results. However, when the slower "Men" query eventually resolves, the state will update again, showing the broader results for "Men," potentially confusing the user who was expecting results related to clothes.
This example shows how race conditions can cause confusing UI behavior. The presenter suggested introducing random delays (0–2000ms) to the asynchronous calls during development. This can help surface such issues, allowing developers to test how the UI handles state when race conditions occur. This technique can be toggled on or off via a flag in the development environment, making it a useful tool for identifying and fixing race conditions.
This will be something I’m taking home and will give a try. I think it’s a valuable test to look into, just to see how the UI manages state when these things happen.
Recommended talks 💡
The conference featured a variety of talks, ranging from entry-level to slightly more advanced. However, if you're a senior or expert React developer, I wouldn’t recommend this conference, as the content might feel too basic. One suggestion for improvement would be to have two tracks: one for all levels and another that goes deeper into advanced topics. This edition felt too easy for us at times, and we found ourselves zoning out.
That said, one talk really stood out, and we loved how the speaker explained React's quirks. The talk was called
About Tim Beeren
A Full Stack Developer, passionate about everything that has to do with creating. From coding, to hosting podcasts or composing music - as long as its a balance between technical and creative skills, I'm in! ☕️