Attendee

React Alicante

In September 2024, I’ve been able to join

React Alicante
with a team of frontend engineers from Bol. Over the course of a few days, we’ve been joining some interesting talks, hands-on workshops, and lots of good foods. From server components to accessibility improvements, the conference covered a wide range of topics. Here are some of my
key takeaways
and insights from our experience at React Alicante 2024.

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

zooming
in on the browser or
reducing motion
for people who feel nauseous due to animations.

This talk taught me not only to use ‘rem’ sizes instead of pixels but also to consider how

containers scale
or how many characters fit on a line using the ‘ch’ unit. It also showed how text can scale linearly, avoiding large UI jumps by using the 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

server components
. Since React 19 was released with server components as the default, it has been a key topic in many talks. I already had a solid understanding of the architectural changes, but I learned new things about server actions and form validation. A particularly cool insight was how actions can function without requiring JavaScript to be enabled.

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

optimize their pages
and carefully consider whether a component needs to render on the client.

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

server side
.

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 "

component hydration
". When a server component is nested within a client component, the server first renders the entire tree, including the server components. The resulting HTML is then sent to the client.

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

"Men"
and then quickly follow with
"Men clothes"
The application might fire two requests due to debouncing. In this case, the first request for "Men" is sent, and then immediately after, the second request for "Men clothes" is sent.

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

"useWat" by David Khourshid
. Through humor, the presenter covered deep React concepts while making it feel like a comedy show. In my opinion, this is how conference talks should be—combining entertainment with education to keep attendees engaged while delivering valuable insights. It helps reinforce the lessons and keeps the audience attentive.

Tim Beeren

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! ☕️

Copyright © 2024 Tim Beeren. All rights reserved.