Home > Back-end >  Memoize API response
Memoize API response

Time:11-12

I have modal which, when opened, makes an Axios get request and returns a QR Code, but I'm trying to cache the QR Code, so when the modal is reopened, the QR Code doesn't need to be re-requested.

I've tried something like:

 const url = window.location.href;

 const qrc = useMemo(async () => {
    return await getQRCode(url).then((res) => {
      return res.data
    });
  }, [url]);

Then in my jsx:

{qrc ? <img src={qrc} alt="qr code" /> : <LoadingDisplay />}

But of course, qrc is still a promise. I'm thinking my syntax is just incorrect, but I couldn't figure it out.

edit:

I've used useEffect with useState, which works, but still re-calls the request every time the modal is re-rendered.

Something like

  const [qrc, setQrc] = useState<string>("");

  const url = window.location.href;

  useEffect(() => {
    getQRCode(url).then((res) => {
      setQrc(res.data);
    });
  }, [url]);

The modal is opened and closed with a button click calling setShowModal(!showModal)

with the jsx: {showModal && <Modal />}

CodePudding user response:

You might want to make the call from a useEffect to get the image source, and store the <img> in a memo.

See: https://codesandbox.io/s/react-qr-code-generator-kjkk9e?file=/src/QRCode.jsx

import { useEffect, useMemo, useState } from "react";

const apiBaseUrl = "https://api.qrserver.com/v1";

const getQRCode = (url, size) =>
  fetch(`${apiBaseUrl}/create-qr-code/?size=${size}x${size}&data=${url}`)
    .then((res) => res.blob())
    .then((blob) => URL.createObjectURL(blob));

const QRCode = (props) => {
  const { url, size } = props;
  const [src, setSrc] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    getQRCode(url, size)
      .then(setSrc)
      .finally(() => setLoading(false));
  }, [size, url]);

  const QRCodeImage = useMemo(() => <img src={src} alt={url} />, [src, url]);

  return <>{loading ? <span>Loading...</span> : QRCodeImage}</>;
};

export default QRCode;
  • Related