As some of you know, we’ve spent the last ~15 months building out react.gg – our take on a modern, interactive React course. We’re happy to announce that it just went live and is now available for purchase.
To celebrate, we’ll be running a discount through launch week – making the course the cheapest it will ever be.
Along with the launch discount, if you buy the course before midnight tonight, we’ll also send you a free Bytes t-shirt (including shipping).
Also, randomly sometime over the next 24 hours, we’ll be picking 2 replies to this Tweet that have 0 engagement (no likes/RTs/or replies) and giving them free access to react.gg and sending them a free t-shirt.
Good luck and welcome to #220 – the react.gg takeover edition.
Line 51: React Hook useEffect has a missing dependency
It’s Saturday morning. The sun is peeking into the kitchen, the kids are still asleep, and you just had your post coffee poop (right on schedule). You’ve waited all week for this. You’re finally going to read the new React docs and binge Dan’s tweets to learn wtf “Server Components” are.
You open Twitter.
“Why is everyone talking about TypeScript? Oh, DHH said something controversial. I wonder what product they just released. Ah, there it is.”
Back to Server Components.
“Wait. Why is Justin Thomas trending? FFS he made the Ryder Cup team. We’ve got no shot. Wonder what Reddit thinks of this.”
The kids wake up, your stomach hurts, and in the back of your mind you remember that you’re still using Angular.js at work and no one is hiring anymore. Maybe next week.
We’ve all been there – but that’s why Bytes exists. React has changed a lot since Cardi B first sang about “macaroni in the pot.” Here’s the breakdown if you haven’t been paying attention.
New Hooks: A few sleeper hooks have been released that smooth out React’s rough parts.
useSyncExternalStore
makes it easier to subscribe to an external data source (for example, anything the browser already manages like localStorage
or matchMedia
) without needing to redundantly duplicate that state as React state in your component.
useEffectEvent
(which is still experimental
but that’s never stopped you before) lets you abstract reactive but non-synchronizing values into their own event handler that can then be used inside of useEffect
without needing to declare it in useEffect
’s dependency array. This is helpful for those “I need to use this in the effect but I don’t want to re-apply the effect every time it changes” moments.
useDeferredValue
allows you to tell React to delay updating a value until all of its high priority work has finished. Why is that helpful? It allows you to give visual feedback to the user by deferring the re-rendering of expensive, non-urgent components.
Other super fun stuff:
startTransition
lets you explicitly tell React which updates are a lower priority. The way it does this is when any updates are wrapped inside of startTransition
, React will treat that update with a lower priority and will interrupt it if a higher priority update like a user event happens.
“Suspense” is a word you’ve probably heard a lot over the years. The whole goal of Suspense is to make reading data over the network as easy as using props or state. In practice, Suspense is just a React component that lets you declaratively specify the loading UI for any part of the component tree if it’s not yet ready to be displayed. It decouples reading the data from the loading UI that’s shown to the user and makes the loading UI a first-class concern that better aligns with React’s programming model.
Server Components allow you to write UI that can be rendered and optionally cached on the server. Because they run on the server, you get a bunch of neat stuff out of the box like earlier and closer to your source data fetching, better security, caching, smaller bundle sizes, faster FCP and easier SEO.
Bottom Line: It took a while, but React seems to be out of the dark ages and has started to hit its stride again lately. Of course, to learn all the latest and greatest in the world of React, check out react.gg.
You need a DevOps wizard, Harry
It’s a tale as old as time: your team wants to build a cloud/serverless app, but then everything goes straight to hell.
Build and deploy times are way slower, you’re locked into a cloud provider that’s suddenly charging you a ton, and you realize that none of you are actual DevOps engineers 🥴.
Don’t worry, Nitric can save you.
Their open-source cloud app framework lets you handle all your infrastructure needs within your code, so your team can ship faster, avoid vendor lock-in, and still get all the power of the cloud.
Here’s how:
Define infrastructure requirements in your code and easily bind code to APIs, events, and triggers (see the docs)
Ship faster by running your cloud apps locally with infrastructure included
Build and test without waiting for deployments to complete
One health tech company said that Nitric made their build and deploy times “magnitudes faster.” And it can probably do the same for you.
Try Nitric for free — it’s like having your own little DevOps wizard in your pocket.
React Native Engineer | ||||
| ||||
We are hiring an experienced React Native engineer who will help us deliver an amazing experience for our mobile users and improve the architecture of our mobile platform. You will work on Motion’s innovative time management platform that helps users organize their schedule and companies efficiently coordinate their work. As one of the first few dedicated mobile engineers on our engineering team, you’ll help set the technical vision for mobile at Motion. |
Frontend Engineering Manager (USA Only) | |||
| |||
Close.com is looking for an experienced full-time Frontend Engineering Manager to join our engineering team and build & lead the 3rd Frontend team. Close is a 100% globally distributed team of 90 happy people, dedicated to building a product our customers love. |
Do you like React? And do you like free Bytes t-shirts? Of course you do. So get the course before midnight and let us help you upgrade your wardrobe for free.
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>
)
}
As if you’re not sick of hearing about React, here are some of our favorite React posts over the years.
In January 2021, Alex Kondov wrote The Tao of React, a very in-depth look at React design, architecture, and best practices that HBO Max is currently turning into a limited mini-series
Why React? is the first lesson in react.gg. It builds on one of our most popular YouTube videos of all time with a text section and some helpful visuals. Because I’m convinced that if you don’t understand why something exists, you’ll never be able master it (which is why I could never master the Gangam Style dance).
Zero created an easy way to integrate 3rd-party API credentials into your project. Their SDK is available for TypeScript, Rust, Python, and Go. [sponsored]
This blog post was originally published in 2015 under the title “React for Stupid People”. We like that title better. But regardless, it’s fun to look back on one of the first viral React posts.
9 years ago Pete Hunt gave this legendary talk at JSConf EU introducing React. Just remember to “Rethink best practices” responsibly because for every Pete Hunt there is a DHH.
10 years ago React was introduced to the world, and despite making all of us a lot of money, it still couldn’t please @raitasorin in the comments who “disliked you for your nonsense speech and bad quality video”.
This is my favorite lesson in react.gg. It goes into Why, When, and How React renders. If this doesn’t help you understand React rendering, nothing will.
Unlayer Embed is a drag-and-drop email editor and page builder for your SaaS application that’s easy to embed and guaranteed to save you weeks of dev time. [sponsored]
In 2019, Rodrigo Pombo showed us all how to Build your own React from scratch. It was a little rude of him to not include anything on server components though.
Our Managing Effects lesson gives you three simple rules for managing effects in React. I got tired of seeing hundreds of developers struggle with it over the years, so I probably spent way too long writing this post and making the video. But if it saves you from dealing with even one linting error, it’ll all have been worth it.
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>
)
}