Skip to content

Instantly share code, notes, and snippets.

export default class DefaultMap<K, V> extends Map<K, V> {
constructor(private init: (key: K) => V) {
get(key: K): V {
if (!this.has(key)) {
const value = this.init(key);
this.set(key, value);
return value;
slikts /
Last active March 15, 2020 12:52
JavaScript build tool overview
slikts /
Last active March 6, 2022 20:41
Up to date answer about when to use React context or Redux (Redux Toolkit)

React context vs Redux in 2020

The [React docs][condoc] give some example use cases for context:

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.

The common property of these use cases is that data like the current theme doesn't change often and needs to be shared deep down the component tree, which would be cumbersome with "[prop drilling][drill]". Something else that needs to be shared everywhere is the application state when using a "single source of truth" pattern, so it would follow that the context API would help with that as well, but there's a catch: components that use context will rerender every time that the provided value changes, so sharing the whole application state through context would cause excessive render lifecycles.

slikts /
Last active April 27, 2024 02:40
Advanced memoization and effects in React

Advanced memoization and effects in React

Memoization is a somewhat fraught topic in the React world, meaning that it's easy to go wrong with it, for example, by [making memo() do nothing][memo-pitfall] by passing in children to a component. The general advice is to avoid memoization until the profiler tells you to optimize, but not all use cases are general, and even in the general use case you can find tricky nuances.

Discussing this topic requires some groundwork about the technical terms, and I'm placing these in once place so that it's easy to skim and skip over:

  • Memoization means caching the output based on the input; in the case of functions, it means caching the return value based on the arguments.
  • Values and references are unfortunately overloaded terms that can refer to the low-level implementation details of assignments in a language like C++, for example, or to memory
slikts /
Last active June 16, 2024 14:24
Why using the `children` prop makes `React.memo()` not work

Why using the children prop makes React.memo() not work

I've recently ran into a pitfall of [React.memo()][memo] that seems generally overlooked; skimming over the top results in Google just finds it mentioned in passing in a [React issue][regit], but not in the [FAQ] or API [overview][react-api], and not in the articles that set out to explain React.memo() (at least the ones I looked at). The issue is specifically that nesting children defeats memoization, unless the children are just plain text. To give a simplified code example:

const Memoized = React.memo(({ children }) => (<div>{children}</div>));
// Won't ever re-render
// Will re-render every time; the memoization does nothing
export const mapStream = <A, B>(f: (a: A) => B, source: Readable) =>
new Transform({
objectMode: true,
transform: (chunk, _, callback) => {
callback(null, f(chunk));
import { Readable } from "stream";
import { EventEmitter } from "events";
const eventToStream = (eventType: string, emitter: EventEmitter) => {
const stream = new Readable({
objectMode: true,
read() {}
emitter.on(eventType, event => void stream.push(event));
slikts /
Last active April 30, 2020 04:00
Jellyfin customization using an nginx reverse proxy

Using nginx HTTP substitution module to customize Jellyfin.

  1. Create /config/custom and place script.js and style.css in it
  2. Edit nginx configuration to serve and inject the script
slikts /
Created November 14, 2019 17:53
Windows aliases with parameters

Replicating bash functions in Windows

Using Win+R to run a command with parameters, similar to bash functions.

mkdir %userprofile%\bin

Add %userprofile%\bin to PATH.

slikts /
Last active October 30, 2023 07:43
Appreciating the elegant simplicity of Immer

Appreciating the elegant simplicity of Immer

There is an ongoing shift in programming towards a more constrained mindset, recognizing shared mutable state and side effects as significant sources of accidental complexity and concepts like immutability and reactive, unidirectional pipelines as ways to overcome it. Simplicity is less optional than before, based on an understanding about the limited capacity of human working memory and based on programming language theory and practice. The functional programming ideas seeping into the mainstream leave less people to say that they wouldn't need them because of maybe never having used them.

The basic idea of controlling complexity through constraints is not novel at all, though, and it raises a valid question about why this shift has taken so long to develop, despite the overall trends towards automation and productivity. For example, the distincti