Exploring Caching Techniques in React

How to use memoization, contexts, useMemo, useState, and useEffect

For future students on the course "React.js Developer" prepared a translation of the material. We also invite everyone to the open webinar โ€œReactJS: Quick Start. Advantages and disadvantages".






What we will create today!  Photo - the author of the article
, ! -

React โ€” . โ€” . , , .





. useMemo



memoization



? useState



context



? , . .





GIF-. ?





!





, , , () . , API, :





export default function handler(req, res) {
  setTimeout(
    () =>
      res.status(200).json({
        randomNumber: Math.round(Math.random() * 10000),
        people: [
          { name: "John Doe" },
          { name: "Olive Yew" },
          { name: "Allie Grater" },
        ],
      }),
    750
  );
}
      
      



, /api/people . , :





  • randomNumber



    : 0-10000.





  • people



    : .





randomNumber



, . . .





, setTimeout



.





People

API, PeopleRenderer.  :





, .





.              .             .





useEffect

- useEffect Hook . ( ), useState :





import { useEffect, useState } from "react";
import PeopleRenderer from "../PeopleRenderer";

export default function PeopleUseEffect() {
  const [json, setJson] = useState(null);

  useEffect(() => {
    fetch("/api/people")
      .then((response) => response.json())
      .then((data) => setJson(data));
  }, []);

  return <PeopleRenderer json={json} />;
}
      
      



(. 11), useEffect



 Hook (-) , DOM (Document Object Model) โ€” . , .   " " Hook ().





useEffect



, DOM, ( ):





. , , . . .





.              .             .





Memoization () 

Memoization โ€” . , , , ,   .





memoized ( , ). , :





const MyMemoizedFunction = (age) => {
  if(cache.hasKey(age)) {
    return cache.get(age);
  }
  const value = `You are ${age} years old!`;
  cache.set(age, value);
  return value;
}
      
      



, , Lodash Underscore, , memoized :





import memoize from "lodash.memoize";

const MyFunction = (age) => {
  return `You are ${age} years old!`;
}
const MyMemoizedFunction = memoize(MyFunction);
      
      



memoization

. getData



, Promise



, . (memoize) Promise



:





import memoize from "lodash.memoize";

const getData = () =>
  new Promise((resolve) => {
    fetch("http://localhost:3000/api/people")
      .then((response) => response.json())
      .then((data) => resolve(data));
  });

export default memoize(getData);
      
      



, . , (memoization) ( (memoized) Promise



, ).





 useEffect



Hook , :





import { useEffect, useState } from "react";
import getData from "./getData";
import PeopleRenderer from "../PeopleRenderer";

export default function PeopleMemoize() {
  const [json, setJson] = useState(null);

  useEffect(() => {
    getData().then((data) => setJson(data));
  }, []);

  return <PeopleRenderer json={json} />;
}
      
      



getData (memoized), , :





Animation: Our components use the same memoized Promise.
: memoized Promise.

, , memoize.tsx



( , ). , getData



, , Promise .





, () , Cache cache (memoized) :





getData.cache = new memoize.Cache();
      
      



, ( Map):





getData.cache.clear();
      
      



Lodash. . :





Animation: Resetting the memoized cache of the getData function.
: memoized getData.

.              .             .





React Context (React )

( ) React Context. , , , Redux. . 





Mark Erikson , . .





, :





Context ()? . - , , , useState



Hook . Context Provider , () .





. -, :





import { createContext } from "react";

export const PeopleContext = createContext(null);
      
      



(wrap) , (renders) People, Context Provider:





export default function Context() {
  const [json, setJson] = useState(null);

  useEffect(() => {
    fetch("/api/people")
      .then((response) => response.json())
      .then((data) => setJson(data));
  }, []);

  return (
    <PeopleContext.Provider value={{ json }}>
        ...
    </PeopleContext.Provider>
  );
}
      
      



12- , . - , , () People:





import { useContext } from "react";
import PeopleRenderer from "../PeopleRenderer";
import { PeopleContext } from "./context";

export default function PeopleWithContext() {
  const { json } = useContext(PeopleContext);

  return <PeopleRenderer json={json} />;
}
      
      



Provider useContext Hook. :





Animation: Using data from the Context.
: Context ().

! "Set new seed". , Context Provider, . ( 750 ) Provider, People . , .





(memoization), . (memoized) useState. , , , . Provider .





.              .             .





useMemo

, , useMemo. Hook , , , : . useMemo



โ€” , , (prop-drilling) ((dependency injection) (, React Context)).





useMemo



. . , , :





export default function Memo() {
  const getRnd = () => Math.round(Math.random() * 10000);

  const [age, setAge] = useState(24);
  const [randomNumber, setRandomNumber] = useState(getRnd());

  const pow = useMemo(() => Math.pow(age, 2) + getRnd(), [age]);

  return (
    ...
  );
}
      
      



  • getRnd



    ( 2): , 0-10000.





  • age



    ( 4): , useState



    .





  • randomNumber



    ( 5): useState



    .





, , useMemo 7- . (memoize) , pow. , age, , . age, useMemo



.





. (re-rendered) age , useMemo



(memoized) .





pow , , , (re-rendered) .





, . -, randomNumber age. , useMemo



( pow (re-rendered) . , โ€œrandomNumerโ€



, (re-rendered) :





Animation: Many re-renders, but pow is memoized with useMemo.
: (re-renders), pow (memoized) useMemo.

, age



, pow



(re-rendered), useMemo



age



:





Animation: Our memoized value is updated when the dependency is updated.
: (memoized) .

.              .             .





JavaScript. , , , .





, , GitLab.





, !






"React.js Developer".



ยซReactJS: . ยป.








All Articles