Skip to content

Instantly share code, notes, and snippets.

View piotr-oles's full-sized avatar

Piotr Oleś piotr-oles

View GitHub Profile
@piotr-oles
piotr-oles / scheduler.d.ts
Last active June 4, 2022 21:23
React's scheduler package API (the most important bits)
// scheduler package API (the most important bits)
type PriorityLevel = number; // currently it's just a number
type SchedulerCallback = () => SchedulerCallback | void; // callback can return "continuation" callback
type CallbackNode = unknown; // we don't need to know how callback node is represented internally
// available priorities
const ImmediatePriority: PriorityLevel; // must run immidiately
const UserBlockingPriority: PriorityLevel; // will run in 250ms at the latest
const NormalPriority: PriorityLevel; // will run in 5s at the latest
const IdlePriority: PriorityLevel; // will run in 10s at the latest
@piotr-oles
piotr-oles / scheduler.ts
Last active June 2, 2022 20:35
Re-export scheduler package API
import {
unstable_ImmediatePriority as ImmediatePriority,
unstable_UserBlockingPriority as UserBlockingPriority,
unstable_NormalPriority as NormalPriority,
unstable_IdlePriority as IdlePriority,
unstable_LowPriority as LowPriority,
unstable_scheduleCallback as scheduleCallback,
unstable_cancelCallback as cancelCallback,
unstable_shouldYield as shouldYield,
unstable_runWithPriority as runWithPriority,
@piotr-oles
piotr-oles / use-transition-effect.ts
Last active June 2, 2022 22:13
Basic hook to run long effects
import { useCallback, useEffect, useRef, useState } from "react";
import {
cancelCallback,
scheduleCallback,
runWithPriority,
ImmediatePriority,
IdlePriority,
} from "./scheduler";
export function useTransitionEffect() {
@piotr-oles
piotr-oles / use-transition-effect.ts
Last active June 23, 2022 04:39
use-transition-effect main api
const [isPending, startTransitionEffect, stopTransitionEffect] =
useTransitionEffect();
@piotr-oles
piotr-oles / start-transition-effect.ts
Created June 21, 2022 20:17
use-transition-effect start transition api
startTransitionEffect(function* () {
for (let item of items) {
doSomeComplexSideEffects(item);
yield;
}
});
startTransitionEffect(function* () {
const cleanup = () => cleanupSideEffects();
for (let item of items) {
doSomeComplexSideEffects(item);
yield cleanup;
}
return cleanup;
});
useEffect(() => {
startTransitionEffect(function* () {
// effect
});
return () => stopTransitionEffect();
}, []);
function App() {
const [isPending, startTransitionEffect, stopTransitionEffect] =
useTransitionEffect();
function handleStartClick() {
startTransitionEffect(function* () {
// do stuff, for example render something on a canvas
});
}
function handleStopClick() {
import { shouldYield } from "./scheduler";
startTransitionEffect(function* () {
for (let item of items) {
doSomeComplexSideEffects(item);
if (shouldYield()) {
yield;
}
}
});
import { runWithPriority, NormalPriority } from "./scheduler";
startTransitionEffect(function* () {
for (let item of items) {
runWithPriority(NormalPriority, () => {
setCount((prevCount) => prevCount + 1);
});
yield;
}
});