Optimistic UI utilities
Improve perceived performance by predicting the future outcome
A set of utilities to achieve Optimistic UI effect. Helps to bridge the gap
between async state changes.
Converting async counter to optimistic component that reacts to user actions instantly:
import React, { useState } from 'react';
+ import { useOptimisticUpdate } from "use-optimistic-update";
export default function UpTo3Counter() {
const [counter, setCounter] = useState(0);
+ const { value, onUpdate } = useOptimisticUpdate("count3r", counter);
const increment = (value) =>
new Promise((resolve) => {
setTimeout(() => {
if (value <= 3) setCounter(value);
resolve();
}, 1000);
});
return (
<button
onClick={() => {
const newValue = counter + 1;
- increment(newValue);
+ onUpdate(() => increment(newValue), newValue);
}}
>
- Likes: {counter}
+ Likes: {value}
</button>
);
}
npm i use-optimistic-update
or
yarn add use-optimistic-update
useOptimisticUpdate
useOptimisticUpdate
is a hook that let’s you sync and update the optimistic state.
import { useOptimisticUpdate } from 'use-optimistic-update';
const { value, onUpdate, isUpdating } = useOptimisticUpdate(
stateKey,
realValue,
);
Options
stateKey: string
realValue: string | number | boolean | undefined
Returns
value: string | number | boolean | undefined
onUpdate: (
updater: () => Promise<void>,
newValue: string | number | boolean | undefined,
) => Promise<void>;
updater
newValue
isUpdating: boolean
stateKey
onUpdate
function
<button
className={}
onClick={() => {
onUpdate(async () => {
await incrementCounter();
}, counter + 1);
}}
>
{counter}
</button>
useOptimisticState
useOptimisticState
is a hook that let’s you retrieve the optimistic state.
import { useOptimisticState } from 'use-optimistic-update';
const { value, isUpdating } = useOptimisticState(stateKey);
Options
stateKey: string
Returns
value: string | number | boolean | undefined
isUpdating: boolean
stateKey
optimist
optimist
is the underlying event emitter used by the hooks. It is responsible
for updating / syncing of optimistic / real values.
optimist.sync
Synchronize the real value with optimist
instance.
import { optimist } from 'use-optimistic-update';
optimist.sync(stateKey, realValue);
Options
stateKey: string
realValue: string | number | boolean | undefined
optimist.update
Update optimistic value inside the optimist
instance.
import { optimist } from 'use-optimistic-update';
optimist.update(stateKey, updater, optimisticValue);
Options
stateKey: string
updater: () => Promise<void>
optimisticValue: string | number | boolean | undefined
optimist.update
import { optimist } from 'use-optimistic-update';
optimist.update(
'count3r',
async () => {
await incrementCounter();
},
counter + 1,
);
optimist.getState
Retrieve the optimistic state.
import { optimist } from 'use-optimistic-update';
const { value, isUpdating } = optimist.getState(stateKey);
Options
stateKey: string
Returns
value: string | number | boolean | undefined
isUpdating: boolean
stateKey
optimist.onUpdate
Retrieve the optimistic state.
import { optimist } from 'use-optimistic-update';
const unbind = optimist.onUpdate(stateKey, listener);
Options
stateKey: string
listener: ({
value: string | number | boolean | undefined;
isUpdating: boolean;
}) => void
Returns
unbind: () => void
optimist.onUpdate
import { useEffect } from 'react';
import { optimist } from 'use-optimistic-update';
useEffect(() => {
const unbind = optimist.onUpdate('count3r', ({ value, isUpdating }) => {
console.log('count3r changes:', value, isUpdating);
});
return unbind;
}, []);
Optimistic UI is a pattern that you can use to simulate the results of a mutation
and update the UI even before receiving a response from the server.
MIT