Caching with React

State Hooks

import React, { useState, useEffect } from 'react';
import expensiveCalculation from './expensiveCalculation';
const StateHooksExample = ({ propA, propB }) => {
const [expensiveValue, setExpensiveValue] = useState(0);
useEffect(() => {
setExpensiveValue(expensiveCalculation(propA, propB));
}, [propA, propB]);
return (
<div>{expensiveValue}</div>
);
};

Ref Hooks

import React, { useRef } from 'react';
import expensiveCalculation from './expensiveCalculation';
const RefHooksExample = ({ propA, propB }) => {
const expensiveRef = useRef(false);
if (expensiveRef.current === false) {
expensiveRef.current = expensiveCalculation(propA, propB);
}
return (
<div>{expensiveRef.current}</div>
);
};

Memo

import React, { memo } from 'react';
import expensiveCalculation from './expensiveCalculation';
const MemoExample = memo(({ propA, propB }) => {
const expensiveValue = expensiveCalculation(propA, propB);
return (
<div>{expensiveValue}</div>
);
});

Dealing with Asynchronous Data

Suspense

import React, { Suspense } from 'react';
import asyncExpensiveCalculation from './asyncExpensiveCalculation';
function expensiveResource() {
let suspenders = {};
return {
get(propA, propB) {
const key = `${JSON.stringify(propA)}${JSON.stringify(propB)}`;

if (!suspenders[key]) {
suspenders[key] = {
status: 'loading',
result: undefined,
promise: asyncExpensiveCalculation(propA, propB)
.then(data => {
suspenders[key].status = 'success';
suspenders[key].result = data;
}).catch(error => {
suspenders[key].status = 'error';
suspenders[key].result = error;
}),
};
}
switch (suspenders[key].status) {
case 'success':
return suspenders[key].result;
case 'error':
throw suspenders[key].result;
case 'loading':
default:
throw suspenders[key].promise;
}
},
};
};
const AsyncComponent = ({ resource, propA, propB }) => {
const asyncExpensiveValue = resource.get(propA, propB);
return (
<div>{asyncExpensiveValue}</div>
);
};
const resource = expensiveResource();const RenderAsyncComponent = () => {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<AsyncComponent resource={resource} propA={propA} propB={propB} />
</Suspense>
);
}

Github Repo

Further Reading

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store