If you’re not using a meta framework like Next.js or Remix, I’d high suggest you check out react-error-boundary.
Seriously, Taran, use this at work.
TIL there’s a useful github repo for bulletproof react!
It gives you a bunch of useufl tips and explanantions on how to make your react code bulletproof.
Check out this dope tool for understanding the React internals! So dope!
Not gonna lie, I’ll probably never need to reach for this tool 😂, but I heard
about it while watching a video on Youtube and thought it was cool.
react-reverse-portal
allows you to render a react node and then take it out of
the dom entirely and return it later, without having to unmount the component.
It’s pretty neat!
While working through my webpack config at work, I noticed the usage of
@loadable/component
. It’s similar to React.Lazy
but solves the issue of SSR
(which is a requirement for my work’s platform).
I haven’t used this yet and today I didn’t have much going on as I had to work on some stuff around the house (renovations and all) but there’s a project that tries to make it a little bit more ergonomic to work with tailwind and React 😊.
Turns out (at least at the time of writing this TIL), that react doesn’t include
the code
property on their Synthetic Events.
So turns out there’s a handy screen that react-testing-library exports. Don’t always have to use the container!
So I’ve seen this pattern around but didn’t know it had a name! If you’ve ever
used Context in React, you’re aware of there being a Provider
and a Consumer
and those two are namespaced to a specific Context. Keep in mind, this is
assuming you’re using React < 16.8.0.
I’m still trying to figure out when this should be used.
const SomeContext = React.createContext()
const SomeContextProvider = ({children}) => {
const [yolo, setYolo] = React.useState(false)
// highlight-next-line
return <SomeContext.Provider>{children}</SomeContext.Provider>
}
const SomeContextConsumer = ({children}) => {
return (
// highlight-next-line
<SomeContext.Consumer>
{context => {
if (context === undefined)
throw new Error('Must be used within a SomeContextProvider')
return children(context)
}}
</SomeContext.Consumer>
)
}
99% of the time you want to be using useEffect
but there are some rare use
cases for useLayoutEffect
and I incidentally ran into one today at work 😂.
useLayoutEffect
if you need to mutate the DOM and/or perform some
measurementsuseEffect
if you don’t interact with the DOM at all.While making my way through a new React course, I learned that React elements
have a $$typeof
property to help mitigate issues with XSS attacks.
In essence, the $$typeof
prevents anyone from trying to get React to create
invalid elements via JSON. Even if a user passed in some JSON that mimicked what
a React Node looks like, the value of $$typeof
is a Symbol
and this cannot
be mocked by JSON!
This technically isn’t something that I learned “today” but it is something that I wanted to make note of! If you’re ever working on a project and need to support internationalization, your library of choice— assuming you’re writing in React— should be react-i18next!
Why? My coworker Vincent wrote up a great ADR (Architectural Decision Record) and evaluated the library and some of the benefits it totes is…
The title sums it up but to learn more about it, visit this link
A neat little concept that I learned about (just briefly) today is this idea of inversion of control. Essentially, assuming that we’re talking about React/Vue components, instead of having a mega component that accepts several different props to handle various things like position, aligment, etc, it sometimes make more sense to have a component that inverts control to the caller.
This means that we can extract out our business logic to a base component and
then have specialized components that utilize the inversion of control to create
a huge combination of different specializations/configurations. For exampe, we
could have a Base Accordion
that implements some core business logic and the
rendering/extending can be left to a specialized implementation like
Left aligned accordion
or All can open acccordion
.
The benefits of this pattern are the following:
A headless UI component is a component that offers up maximum flexibility by providing no interface itself! This sounds like a radical idea but for library authors, it’s a great pattern to provide their users with all that sweet sweet functionality that they’re craving without any of the bloat/stylystic decisions that come with interface decisions.
This pattern works great when the logic of a component is complex and can be decoupled from its visual representation.
From a React
perspective, this can be acheived via an HOC, render props, or if
you’re using React > 16.8
, hooks. Below is an example of two different
interface implementation of a very simple toggle — the state isn’t complicated
but since we created this headless interface, the UI can easily be
changed/edited and does not suffer from the opinions of the library author!
class Toggle extends React.Component {
state = {
on: false,
}
handleClick = (cb = () => {}) => evt => {
this.setState({ on: !this.state.on }, () => cb(evt))
}
render() {
const { state, handleClick } = this
return this.props.children({ state, handleClick })
}
}
function CheckBox() {
return (
<Toggle>
{({ state, handleClick }) => {
return (
<input
type="checkbox"
id="scales"
name="scales"
checked={state.on}
onChange={handleClick()}
/>
)
}}
</Toggle>
)
}
// Just some simple styled components
// to illustrate how we can decouple the styling from the logic
const Label = styled.label``
const Input = styled.input``
const Slider = styled.span``
function PrettyToggle() {
return (
<Toggle>
{({ state, handleClick }) => {
const appliedHandleClick = handleClick(console.log)
return (
<Label>
<Input
type="checkbox"
checked={state.on}
onChange={appliedHandleClick}
/>
<Slider />
</Label>
)
}}
</Toggle>
)
}
function useToggle(cb = () => {}) {
const [on, updateClick] = React.useState(false)
const event = React.useRef()
React.useEffect(() => {
cb(event)
}, [on])
return {
on,
handleClick(evt) {
event.current = evt
updateClick(!on)
},
}
}
function HookPrettyToggle() {
const { on, handleClick } = useToggle(console.log)
return (
<label class="switch">
<input type="checkbox" checked={on} onChange={handleClick} />
<span class="slider round"></span>
</label>
)
}
function HookCheckBox() {
const { on, handleClick } = useToggle()
return (
<input
type="checkbox"
id="scales"
name="scales"
checked={on}
onChange={handleClick}
/>
)
}