I've been seeing this pattern quite a bit:
// inside a component
const dimensions = useRef<DOMRect | null>(null)
useEffect(() => {
dimensions.current = someRef.current.getBoundingClientRect()
}, []);
COLORS = [ | |
'#3366CC' | |
, '#DC3912' | |
, '#FF9900' | |
, '#109618' | |
, '#990099' | |
, '#575acb' | |
, '#ebdb0c' | |
, '#ed2467' | |
, '#66AA00' |
V8 | |
{ | |
'react:equal:monomorphic': { average: 1206.33, stddev: 59.63406930792349 }, | |
'react:unequal:monomorphic': { average: 1198.67, stddev: 41.51572660517404 }, | |
'hughsk/shallow-equals:equal:monomorphic': { average: 595.33, stddev: 33.47967874530592 }, | |
'hughsk/shallow-equals:unequal:monomorphic': { average: 559.33, stddev: 1.699673171197595 }, | |
'romgrk-fastCompareUnsafe:equal:monomorphic': { average: 510.33, stddev: 1.247219128924647 }, | |
'romgrk-fastCompareUnsafe:unequal:monomorphic': { average: 447.67, stddev: 2.0548046676563256 }, | |
'romgrk-fastCompareStrict:equal:monomorphic': { average: 881.33, stddev: 1.699673171197595 }, | |
'romgrk-fastCompareStrict:unequal:monomorphic': { average: 775.33, stddev: 0.9428090415820634 }, |
// | |
// Event-based reactivity with events corresponding 1:1 with state properties | |
// I use "path" and "event" interchangeably. | |
// | |
// Example state model | |
type State = { | |
virtualization: { | |
offsetTop: number, | |
renderContext: { |
/* | |
* Skipping over internal reactivity but this would be the gist of how to build a component that doesn't | |
* use react but still allows customization via user-supplied react-based render functions. | |
* | |
* Why? Because react is way to slow for use-cases like virtualization+scrolling. The whole cycle (state-update | |
* then re-render then vdom diffing then dom update) has too many unavoidable costs. Being able to go from | |
* state-update to dom-update directly is unbeatable. | |
* | |
* It uses react portals, so even though it manages its own HTML structure, it contains inside itself parts that | |
* are rendered & managed by react. And portals ensure there is full react compatibility, including the Context API, |
I've been seeing this pattern quite a bit:
// inside a component
const dimensions = useRef<DOMRect | null>(null)
useEffect(() => {
dimensions.current = someRef.current.getBoundingClientRect()
}, []);
body { | |
--sk_primary_background: 38,38,38 !important; | |
} | |
.c-wysiwyg_container--theme_dark, | |
.c-wysiwyg_container__formatting, | |
.then { | |
background-color: #212121 !important; | |
} |
// ==UserScript== | |
// @name github-notifications | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description try to take over the world! | |
// @author You | |
// @match https://github.com/notifications | |
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | |
// @grant none | |
// ==/UserScript== |
I usually like to wrap React useEffect
calls inside other functions, such as useOnMount
, useOnChange
, useOnceTrue
, etc. I've often had pushback on that, and the argument is usually "it's another abstraction layer to learn", which is a fair point. I thought I'd summarize why I think this layer of abstraction is beneficial.
One of the reasons why we use Array methods like .filter
, .map
or .reduce
instead of using a generic for (...)
loop despite their lesser performance is that they provide a higher level of expressiveness, and they make the underlying logical operation much more semantically apparent.
For example, the two following snippets perform the same operation, but the second one makes it abundantly clear with just a glance that there is a filtering operation happening.
const newItems = []
const is = Object.is; | |
export function fastObjectShallowCompare<T extends Record<string, any> | null>(a: T, b: T) { | |
if (a === b) { | |
return true; | |
} | |
if (!(a instanceof Object) || !(b instanceof Object)) { | |
return false; | |
} |
/* | |
* Usage: | |
* | |
* const abContext = Store.createContext() | |
* | |
* function Parent(props: { a: number, b: number }) { | |
* return ( | |
* <Store.Provider context={abContext} value={props}> | |
* <ChildrenA> | |
* <ChildrenB> |