Today’s issue: Building a UI that’s “boneless and skinless”, figuring out how React renders, and sharing our hot takes about CSS Grid and Charlie Brown.
Welcome to a Butterfinger-fueled #337.
When your app is slow, but you get to use React.
Most of my neighbors didn’t understand why I dressed up as a bottle of Sweet Baby Ray’s last night. But I was actually dressed as the specific BBQ sauce bottle in Mark Zuckerberg’s smoking meats video from 2018 for a very important reason.
That video came out the very same month that the React Native team at Facebook announced they were starting to rewrite RN’s architecture. And since they finally just finished last week, I wanted to bust out the BBQ sauce costume to celebrate 🎉.
Let’s talk a little more about why the team has spent the last 6.5 years rewriting React Native, and how things look different now in v0.76.
Quick review: The old architecture used an asynchronous bridge that enabled React Native to communicate with the native platform via serialized JSON messages. This created performance issues, which stemmed from too many JSON messages needing to go through a single communication channel (among other things).
So, the React Native team decided to build a New Architecture from the ground up that now consists of three main parts:
A new native module system allows JavaScript and the native layer to synchronously communicate via a new C++ API. This removes the need to JSON-ify data.
A new concurrent rendering system supports more responsive UIs and can handle multiple progress trees across multiple threads.
A new event loop can now process tasks on the JavaScript thread in a well-defined order, allowing React to interrupt rendering to process higher-priority user events.
Bottom Line: The old bridge has officially been burned, the new architecture is now the default, and React Native looks ready to enter its golden era. I’ll bring the meats.
Mfw I build my entire backend with other people's components
They work just like frontend components – but instead of giving you a generic-looking navbar, they give you scalable backend features with all the best practices baked in.
Need to build some cron jobs? Just run npm i @convex-dev/crons
, and you’ll be able to dynamically register and manage cron jobs at runtime (see docs).
All the components come with a clean npm package, a well-documented API, and fully sandboxed data and code – so they’re safe and easy to use.
Here’s a few more things they can help you build:
Database features for real-time data management & sync, like counters and migrations.
Durable functions for long-running and resilient background tasks, like crons and workflows
Backend infrastructure features like a rate limiter and action cache.
Third-party integrations for Expo push notifications, Twilio SMS, LaunchDarkly, and other services
Try out the components – they’re open source and free to use.
How would you remove the duplicate elements from this array?
const list = [
{ name: 'John' },
{ name: 'Sara' },
{ name: 'Sara' },
{ name: 'Lynn' },
{ name: 'Jake' }
];
Last week’s React Native release also gave us the first stable version of the React Native DevTools. Still no word on how long until we get RN 1.0, but let’s check back in another 6.5 years.
If you’ve ever thought to yourself, “why tf is this rendering?” – The Interactive Guide to Rendering in React is probably for you.
Adam Argyle wrote a Halloween-themed article about headless, boneless, skinless, & lifeless UI. Because sometimes it’s fun to let the dark thoughts win.
Tests are dead – because Meticulous is a new tool that creates and maintains a continuously evolving e2e UI test suite for you, with zero effort and zero flakes. Companies like Lattice and Bilt Rewards are already using it for all their frontend testing, and it looks pretty game-changing. [sponsored]
The Next.js team created this quick recap of Next Conf, in case you were also banned from attending unable to make it.
Wasmer just released v5.0 of its fast and secure Wasm runtime that now has iOS support and experimental support for V8 and other backends.
austinoaq created this single Vanilla JavaScript file that shows the basic principles of how React, Vue, and Angular work.
CarbonQA gives your team high-quality QA services that scale, with US-based testers who work directly alongside you in your tools (Slack, GitHub, Jira, Asana, etc.). They’ll break your app repeatedly and find all the errors for you, so your devs can just focus on being devs. [sponsored]
Adam Wolf wrote a visual blog post about rendering outlines with a post-processing shader.
Ahmad Shadeed wrote an article that dares to ask, Should masonry be part of CSS grid? That’s almost as controversial as my take that Linus should’ve just gone trick-or-treating with all his friends in Charlie Brown and The Great Pumpkin, instead of spending all night alone in a pumpkin patch waiting for pumpkin-Santa to bring him stuff.
How would you remove the duplicate elements from this array?
const list = [
{ name: 'John' },
{ name: 'Sara' },
{ name: 'Sara' },
{ name: 'Lynn' },
{ name: 'Jake' }
];
There are a few ways to do this. Your first intuition might be to do something like this.
const uniqueList = Array.from(new Set(list))
It’s the right idea since creating a Set
will ensure our collection only contains unique values and Array.from
allows us to create a new, shallow-copied array. Unfortunately, Sets
only enforce uniqueness for primitive values, but our list is full of objects.
Instead, we can do something like this.
const map = new Map();
list.forEach(item => {
map.set(item.name, item)
});
const uniqueList = Array.from(map.values())
Notice we’re using a Map
here. Since Map
’s preserve insertion order, our uniqueList
will have the same order as the original list, but without the duplicates since we’re using name
as the key.
Another fancy approach is using filter
with findIndex
,
const uniqueList = list.filter((item, index) =>
list.findIndex(({name}) =>
name === item.name
) === index
);
Or using .reduce
and .map
,
const uniqueList = Object.keys(
list.reduce((acc, cur) => {
acc[cur.name] = cur.name;
return acc;
}, {}),
).map((name) => ({ name }));
Or one of the other various ways that I’m sure you’ll all let me know about 🫶.