Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 30, 2022 07:41 pm GMT

Optimizations in React Part 2

To useMemo or not to useMemo?

You might have noticed that our CoolButton
doesn't properly render the + sign

<CoolButton clickHandler={increment}>+</CoolButton>

When inserting anything inside a JsxElement we don't present it to the user but pass it to our JsxElement as a prop called children
and to render it we need to render out the children
inside CoolButton

const CoolButton = React.memo(({ clickHandler,children }) => {    const handler = () => {        ReallyImportantCalculation();        clickHandler();    };    return <button onClick={handler}></button>;  });

Lets render out the children:

return <button onClick={handler}>{children}</button>;

Just as before, let's add some complexity to our design.

Instead of presenting the user with the (+) sign, let's create a 'Clicker' game, it will consist of a button that changes it's appearance based on the number of times we clicked it.

We can start by passing an <img/> instead of a + sign to our CoolButton

<CoolButton clickHandler={increment}>  <img/></CoolButton>

When clicking the button we notice that our memoization was lost once again; re-rendering the button on every click..

Let us remember that in JSX <img/> is not an html tag, it's actually a shorthand for React.createElement('img',props, ...children)

Turning our code into:

{createElement(CoolButton,{clickHandler:increment},  createElement('img',null, null))}

Now it's easy to see the exact problem, running createElement on every render causes it to create a new child thats being passed to our CoolButton as a prop.
First thing is to stop calling the createElement on every render

const CurrentImage = <img/>;<CoolButton clickHandler={increment}>  {CurrentImage}</CoolButton>

You might be tempted to put the CurrentImage outside of our Counter, which would work, but seeing as CurrentImage will have a state based on our Counter we should use a different way:

const CurrentImage = useCallback(<img/>,[]);<CoolButton clickHandler={increment}>  {CurrentImage}</CoolButton>

Just like before, useCallback to the rescue, looks a bit weird though as our CurrentImage is not really a callback but a value we want to memoize.
Let's use something else.

useMemo

useMemo and useCallback can be used interchangeably(From React docs)

As we said, the Children prop we pass to our CoolButton changes on every render since we create a new CurrentImage on every render, we can useMemo to memoize that Element.

const CurrentImage = useMemo(() => <img/>,[]);<CoolButton clickHandler={increment}>  {CurrentImage}</CoolButton>

useMemo just like useCallback, takes a function that memoizes something and a dependency array that re-runs that function only when the dependencies change, in our case we want to memoize a JsxElement.

Let's add a new state called phaseImgUrl which will tell us what Image we should be presenting for every phase of our Clicker

const [phaseImgUrl, setPhaseImgUrl] = useState('');const CurrentImage = useMemo(() => <img src={phaseImgUrl}/>,[phaseImgUrl]);<CoolButton clickHandler={increment}>  {CurrentImage}</CoolButton>

Some extra logic that will handle changing the phases when reaching a certain threshold

const phases = [  "https://media4.giphy.com...phase1",  "https://media4.giphy.com...phase2",  "https://media4.giphy.com...phase3",];useEffect(() => {    if (count != null) {      const phaseThreshold = 30;      const numPhases = phases.length;      const nextPhaseImgUrl =        phases[parseInt(count / phaseThreshold, 10) % numPhases];      if (nextPhaseImgUrl !== phaseImgUrl) {        setPhaseImgUrl(nextPhaseImgUrl);      }    }  }, [count]);

First we check if the count is valid, then it's important to make sure that the phase is different from the last one, so we don't cause extra setStates and re-renders.

And there we go with some extra effects which we will talk about on the next part:


Original Link: https://dev.to/vithano/optimizations-in-react-2-242k

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To