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
Ivan Montiel

Ivan Montiel

UI Engineer at Lacework. Founder at Clarity Hub.