Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
So we'll learn about useCallback.
Attached, you find a new mini example
where I also wanna dive into another hook
that helps us with another optimization we could add.
Here we have useCallback
to basically store a function to not recreate it.
This is a function which I pass to the Button
through the onClick prop.
The Button internally uses React.memo.
And because we store that function with useCallback,
the Button will never re-render in this case
because its props never change, and React is aware of that.
Now, I'm also rendering a list here,
and the interesting thing is that the list is sorted.
It's sorted in ascending way.
Now, the data which I put into the list is not sorted.
It's in random order, as you can tell here.
So that means that, of course, obviously,
in the list we're doing some sorting.
And, indeed, here I'm sorting my list
with this simple built-in sort method
to which I just pass a function
that defines how the sorting should happen,
you can look up the sort method documentation
if you wanna learn more about that,
and that gives me my sorted list which I then output.
Now, the thing is sometimes in your code,
sometimes in your components, you might have logic like this
which could be a bit more performance-intensive.
Obviously, that's a short list, sorting will be quick.
But for longer lists, or simply for other tasks,
you might have some code which takes quite some time.
Eventually, this code, of course, needs to execute,
but you certainly don't want to run this code
every time the entire component is re-evaluated.
Now, of course, we learned what we can do
to avoid unnecessary re-evaluations.
We can use React.memo here, right?
With that, we can wrap the DemoList.
With this, this shouldn't run unnecessarily.
If I now console.log DemoList RUNNING here,
we see that, of course, it runs initially.
That means the list was sorted,
but thereafter it shouldn't run again.
Well, actually, I have this button.
When I click it, I change the title here,
and the title is part of my list here.
Therefore, when I click the button, DemoList runs again,
and it needs to run again
because one of its props changed, the title changed.
It has a real different value there.
So React.memo is not failing.
It needs to rerun in this case.
Now, as a side note, of course,
currently it would always rerun
when the parent component re-renders, though,
because at least this array here
is constantly recreated in the parent component
whenever the parent component runs.
So even if the title would not change,
if the parent component would rerun for some other reason,
the DemoList component would be re-executed
because we always generate a new array.
Like functions, arrays are objects.
Objects are reference values.
And therefore, two arrays,
even if they have the exact same elements
and the same order, are never the same
because they occupy two different places in memory.
But here we don't even have the problem,
but instead, as I just explained, because the title changes,
we have a valid reason to rebuild DemoList.
So sometimes the component reruns is re-evaluated.
And still, you might not want to repeat
every bit of work you did there in the past,
especially if the work you would have to redo
is more performance-intensive.
And sorting is one of the more performance-intensive tasks
you can do in your components.
So, is there a solution to that? Yes, there is.
We have useCallback to store function objects
and only rebuild them when some input changed.
We have something similar for all other kinds of data,
and that is another hook which we can import,
the useMemo hook.
useMemo basically allows you to memoize,
so basically that means to store,
any kind of data which you want to store,
just like useCallback does it for functions.
And here we could memoize,
and, yes, that's memoize, not memorize,
these are two different terms,
but it's pretty much the same here in this context,
so you can memoize the result of this sorting here
simply by calling useMemo here,
and now useMemo, as a first argument, wants a function.
That is, however, not a function that will be memorized.
Instead, that function should return what you want to store,
so in this case it should return that sorted array.
Now, just like useCallback, useMemo wants a second argument
which is an array of dependencies,
basically to ensure that this stored value is updated
whenever one of the values you're using in there changes.
And in this case, indeed, whenever items changes,
whenever we get new items, we wanna re-sort them,
so items are a dependency here.
We could add props here
because items are pulled out of props,
but that means that the entire props object
is our dependency,
and therefore this would essentially always recalculate.
So a more elegant way is something we used on useEffect
and its dependencies earlier in the course.
We can use destructuring to pull something out of props,
in this case to pull the items out of props.
And then we can just add the items here as a dependency
and use just items here for sorting.
And now this will only rebuild this if items changed.
Now, let's see when that happens.
For that, I can add a console.log here, Items sorted.
Let's see how often this runs.
If I reload, we see it runs initially, of course,
but it still also runs when I change the title.
Now, the idea was that it shouldn't run there.
Why is it running again then?
Well, because items de-changed.
That's what I mentioned earlier, a few minutes ago.
The items here actually are always recreated when App reruns
because we always create a new array here.
So even if it's technically a similar array
with the same values and the same order,
it's still technically a new array in memory,
and that is treated as a brand new object
which isn't the same as the old array
even if it contains the same values.
That's this reference value thing
I mentioned a couple of times
throughout this module already.
So to ensure that we don't unnecessarily pass
a new array here,
we can, of course, also use memo here.
We simply import useMemo.
And then here, we can wrap it at this function
which should return this array
and add our dependencies which here is an empty array.
We get empty dependencies array here
because here this, of course, never changes.
It has no external dependencies.
It's all hard-coded in here.
So, therefore, now we also call useMemo here.
And, of course, we can also pull it out of there
and say listItems is the result of calling useMemo,
and then we pass listItems here to items.
And with that now,
we should not unnecessarily sort the list again.
Now, we see items sorted initially.
But if I click Change List Title,
we don't see it again because of useMemo.
Now, I will say you will use useMemo far less often
than you use useCallback
because memorizing functions is much more useful,
and you need that more often than memorizing data.
You essentially wanna memorize data
if it would be performance-intensive
to recalculate something based on it.
Otherwise, it might not really be worth it
because you always have to keep in mind
that if you store data with useMemo,
of course, it occupies some memory
and, of course, this storing functionality
also takes up some performance.
So this is not something you wanna use
on every value you're using.
If you got a scenario like this one here, though,
where you wanna sort something,
then it might be worth a look because then using useMemo
and avoiding unnecessary sorting steps
in future component updates,
that might be very well worth it.
Now, throughout this course,
of course, we'll see more examples.
And therefore, throughout this course alone,
you will get a better feeling for when you wanna use what.
In this module, I just wanna put all those things out there
and explain them so that you understand them
and so that you are aware of them.
When you use them always comes with experience,
depends on your preferences, your exact use case,
and there also isn't a clear right or wrong.
It's just something you should be aware of
so that you can look into optimizations like this
if you find out that your application is slow
or that you wanna improve some parts of your application.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.