React 18 finally out and new CSS features in Safari
This week the new React version (18) was finally released. I'll go over exactly what this implies. Also the Safari Technology Preview was announced that includes support for a ton of CSS features.
🗞 console.log(news)
React 18
React isn’t losing steam anytime soon. The previous version 17 update had changed more so to do with the infrastructure to make future updates easier. So this version 18 has a lot more functional changes! The following are my personal highlights of the new version:
Concurrency
This is probably one of the biggest features announced for the new React and one we won’t have to actively use.
TLDR: React is now more responsive and fluid.
Previously React renders were “uninterruptible” (their words) but now React can intelligently decide which renders and updates need to be paused, continued, or completely stopped altogether whilst making sure the UI continues to be intact. What this means is that the user is able to interact much quicker without having to wait for the render to complete in every case.
useTransition
One common issue with React is updating the contents of an input field on every keystroke would cause a re-render. There was a workaround for this such as using a useRef or debouncing the input.
But, not React offers useTransition which allows the developer to mark a state update (render) “as not urgent.” With this, we can delay the input and render until the end.
Effectively a debounce for inputs. Awesome! This will probably have tons more uses but this was the first that came to mind.
An example:
function Input() {
const [isPending, startTransition] = useTransition();
const [text, setText] = useState('');
function handleInput(e) {
startTransition(() => {
setText(e.target.value);
})
}
return (
<div>
{isPending && <span>Transitioning....</span>}
<input onChange={(e) => handleInput(e)} value={text} />
</div>
);
}
useDeferredValue
In the same vein, another hook was released: useDeferredValue. One common scenario is that there are other components that are re-rendered from a value changing quickly. useDeferredValue allows the component to defer back to an old value while “urgent updates” are occurring.
const [value, setValue] = useState('');
const deferredValue = useDeferredValue(value);
const deferredChildComponent = useMemo(() =>
<ChildComponent value={deferredValue} />,
[deferredValue]
);
The caveat is that the dependent components need to be memoized. Now the component will use the old value while the new one is being completely updated. Essentially a debounce but without an arbitrary amount of time for the debounce.
React decides the best time to set the new value and rerender.
TLDR: Optimized and native debounce
useId
This is a new hook offered by the API to generate unique IDs which may not seem that crazy but it works on both the server and client. This is especially useful now that everything seems to be trending towards SSR.
const id = useId();
Server Components
These are components that, again, contribute to the trend of SSR. Components that are streamed through server rendering but are still in development. I’ll go more in-depth on these when they officially get released.
New CSS features in Safari
Safari the past year had been starting to feel like the new Internet Explorer 🤢. Lacking a lot of compatibility with modern browser functionalities. Many web developers will know the struggle of Safari having slightly different UI changes because of the way the HTML/CSS is validated.
However lately Safari has been quick on releasing updates to really modernize the way it can compete with other browsers. 🚀
This is probably a good time to go over some of the implemented new CSS features (before only available in Firefox):
CSS Subgrid
CSS Container queries
CSS Subgrid
CSS grid is powerful! And now another tool in the toolbox has been added. We can now specify an item’s columns or rows as a subgrid of a parent grid. But what does this mean?
.grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
}
.subgrid {
display: grid;
grid-column: 2 / 4;
grid-row: 2 / 4;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
In the above example, the subgrid class sets its own grid-template-columns and grid-template-rows to be the same amount of columns and rows its occupying in the parent grid.
CSS Container queries
A powerful and highly anticipated feature. This will allow developers to use media query type syntax but instead of validating it with the viewport, we’d be able to do it with the parent container.
To declare a container:
.container {
container-type: inline-size;
container-name: foobar;
}
@container foobar (min-width: 5rem) {
.innerComponent {
// ...change the styles
}
}
We declare a container-type
and container-name.
This allows us to query it directly. This will be huge for component-based layouts.
💡 (() => { /* Learning */ })();
When I first created my blog I initially did so with WordPress just to start writing ASAP. Didn’t want to worry about design, hosting, or anything else. But, now I want to make my own website for my blog.
I’ve really been enjoying Remix. A React Framework with progressive enhancement and an API layered on top of the native APIs. It just feels right.
Anyway, I’ve started out with the header and decided to start dusting off the old CSS skills. Here’s a quick look at my dark mode button (first iteration):
It was fun brushing up on the CSS. This was made with tailwindcss.
🎉 fetch(meme).then(…
An all too common feeling. Should have fixed it back then.