5 Big Things from React Conf

Issue #289.May 16, 2024.2 Minute read.
Bytes

Welcome to React Conf-apalooza 🥳.

Today’s issue: The Jets vs Sharks of the React team, Vercel is rich rich, and chain smoking to feel like you’re part of the fun in Vegas.

Welcome to #289.

If you're reading this...

You either haven't opened an issue in a while, or you really care about your privacy and we can't tell (which we're cool with).

Regardless, the Email Overlords™ punish us if we send emails that don't get opened.

If you'd like to keep receiving Bytes, you'll need to click the link below to opt back in. If you don't, you'll be removed.

Keep Receiving Bytes


Eyeballs logo

The Main Thing

A slide from React Conf with lots of React community members' faces on it

Choose Your Fighter

5 Big Things from React Conf

Sure, my brain might be slightly fried from watching 10 hours (and counting) of React Conf – but I’m a professional.

That’s why I just professionally chugged a Red Bull mixed with Mtn Dew Baja Blast and am now fully ready to flip a minivan with my bare hands break down the top 5 biggest headlines from React Conf so far.

Let’s dive in.

#1 React Compiler goes open source. This build-time tool is still experimental for now, but it promises to save us all from useMemo hell by automatically memoizing our React code with minimal impacts on memory. Not only will this improve performance by preventing unnecessary re-renders, it’ll also make your React code a lot more clean and concise without all that extra memoization code.

#2 Remix merges with React Router. Convincing teams to migrate is hard, so the Remix team decided to turn their Remix v3 release into a React Router v7 release instead. This entails adding a Vite plugin to React Router while the Remix packages “take a little nap” (their words).

#3 React 19 releases its first RC. Andrew Clark spent most of his talk diving deep on React Actions, a first-class pattern for async data updates in response to user input, which we wrote about recently.

#4 Universal server components are coming to Expo. Evan Bacon gave an awesome live demo of RSC in Expo Router, featuring server rendering native views, streaming UI, and parallel data fetching in one unified system for all platforms. And it suddenly makes sense why Expo Router has started calling itself “the universal React framework.”

#5 React isn’t going anywhere. Despite some of the (justifiable) frustration with React in recent years, it’s looking stronger than ever as it heads into a brand new era. React’s npm downloads have grown almost 2x since last React Conf to over 1 billion per year (more than double every other JavaScript framework combined), and it’s addressing many of its weaknesses in innovative ways.

There’s still a lot to be done, but next time you read another “React is dead” think piece, you might want to take it with a grain of salt.

        

stytch-logo.png

Our Friends
(With Benefits)

Sad looking woman with equations written all around her

Thinking about all the custom backend code you need to write for each new enterprise user

Build B2B auth that your future self will thank you for

Your auth solution was working fine – until you started scaling to enterprise customers. Now you’re stuck hacking together random tools, writing janky custom code, and questioning all your life choices.

But there’s a way out: go back in time and start using Stytch from the beginning.

Their auth architecture is purpose-built for multi-tenant apps, so you get everything your B2B customers need out of the box:

  • API-first flexibility lets you add SSO, MFA, RBAC, and more with a simple API call (see docs)

  • All-in-one approach saves time and complexity by giving you auth, device fingerprinting, and bot detection in a single platform

  • Brand new B2B features like pre-built UIs for MFA, protected email magic links, and Google One-Tap support

Try out Stytch – and see how teams like Zapier, Hubspot, and Cisco have saved months of work by switching to Stytch.


Spot the Bug logo

Spot the Bug

Sponsored by Bright Data

Their Web Scraper API makes it possible for companies like Microsoft, McDonald’s and eToro to scrape web data from the most complicated websites at scale, without being blocked.

export default function App() {
  const [count, setCount] = React.useState(0)
  const [delay, setDelay] = React.useState(100)
  const [step, setStep] = React.useState(1)

  const handleDelayChange = (d) => setDelay(d)
  const handleStepChange = (s) => setStep(s)

  React.useEffect(() => {
    const id = window.setInterval(() => {
      setCount((c) => c + step)
    }, delay)

    return () => window.clearInterval(id)
  }, [delay, step])

  return (
    <main>
      <h1>{count}</h1>
      <Slider
        min={100}
        max={2000}
        step={100}
        onChange={handleDelayChange}
        label="ms delay"
      />
      <Slider
        min={1}
        max={10}
        step={1}
        onChange={handleStepChange}
        label="increment by"
      />
    </main>
  )
}

Cool Bits logo

Cool Bits

  1. If you can’t wait to get your hands on the still-experimental React Compiler, I’d recommend poking around the React Compiler playground instead of adding it to prod. But I support your life choices either way.

  2. Split created this case study on Moving Faster and Safer – which shows how they helped one team go from 2 deployments per day to 64 deployments per day by “learning to break things responsibly.” Sadly, they weren’t around back in 2011 to teach my college roommate how to “break things responsibly” when he was coming home drunk at 1:00 am 😭. [sponsored]

  3. Vercel just announced that they raised $250 million. And if that doesn’t convince your manager to let you start using server components, nothing will.

  4. Suni Pail gave a great talk about real-time React Server Components with PartyKit.

  5. Datadog created this free report on 10 insights of real-world container usage by examining over 2.4 billion containers run by thousands of their customers. [sponsored]

  6. React Native’s new architecture is now in beta and so close you can almost taste it, release your inhibitions, feel the rain on your skin.

  7. Lauren Tan shared some encouraging React Compiler case studies from its rollout to various apps at Meta.

  8. The React Team Q&A gave some interesting insight about the future of React and featured an unintentional Jets-vs-Sharks walkout moment between the Vercel and Meta team members.

  9. Get high-quality QA services for your dev team with CarbonQA. Their US-based testers will break your app repeatedly, so you never have to waste eng time on QA testing again. [sponsored]

  10. They open-sourced the React Conf App, so you can feel like you’re really there. And for the full Las Vegas React Conf experience, you could spend $999 on a fake “ticket”, stay up til 4 am playing online poker, and start chain smoking with all the windows closed in your house.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Bright Data

The bug is that we’re unnecessarily removing and re-adding the interval whenever delay or step changes.

We want to be able to access the reactive step value from inside of useEffect, but we don’t want to include it in the dependency array because it has nothing to do with setting and removing the interval.

This is the perfect use case for React’s new experimental hook, useEffectEvent. You can abstract the reactive but non-synchronizing logic into useEffectEvent, then you can use that event handler inside of useEffect without needing to include it as a dependency in the dependency array.

import * as React from "react"
import Slider from "./Slider"

React.useEffectEvent = React.experimental_useEffectEvent;

export default function App() {
  const [count, setCount] = React.useState(0)
  const [delay, setDelay] = React.useState(100)
  const [step, setStep] = React.useState(1)

  const handleDelayChange = (d) => setDelay(d)
  const handleStepChange = (s) => setStep(s)

  const onInterval = React.useEffectEvent(() => {
    setCount(count + step)
  })

  React.useEffect(() => {
    const id = window.setInterval(onInterval, delay)

    return () => window.clearInterval(id)
  }, [delay])

  return (
    <main>
      <h1>{count}</h1>
      <Slider
        min={100}
        max={2000}
        step={100}
        onChange={handleDelayChange}
        label="ms delay"
      />
      <Slider
        min={1}
        max={10}
        step={1}
        onChange={handleStepChange}
        label="increment by"
      />
    </main>
  )
}