Loading video player...
Now that we have seen how to use use
reducer with simple and complex state
and action, there is one more feature of
use reducer I want to show you and that
is lazy initialization. You might
remember this from our earlier lesson on
use state. We learned that ustate can
accept a function when the initial value
requires some extra work. React calls
that function only once during the first
render. It is perfect for situations
where calculating the initial value is
expensive. Well, guess what? User
reducer has this feature too. The
pattern looks a little different, but
the idea is exactly the same. Let me
show you. We will stay with our counter
example for now. This time, instead of
always starting from zero, imagine we
want the counter to start from a value
stored in local storage. For example, a
value saved from a previous session. So
in the source folder create a new file
called counter within init.jsx
and copy the code from counter with
reducer.jsx
file and paste it. Update the component
name to counter with init. So far this
is the same setup we already know. State
is a number and actions are just
strings. increment, decrement and reset.
Now we will add lazy initialization on
top of this. With use state, we passed a
function as the initial value. With use
reducer, we keep the initial state as
the second argument, but we add an
optional third argument, an init
function.
Let's define this init function outside
the component. con inital
function. The init function receives one
argument which is whatever we pass as
the second argument to use reducer. In
our case that is initial state or
initial count with a value of zero.
So specify initial value within the
function body. First we will add a
console log to see when the function is
called. Init function called this only
runs once. Next we try to read count
from local storage. So const save count
is equal to local storage dot get item.
And let's assume count is what we store.
If we find a value, so if saved count is
not equal to null, we parse it and
return it. Let's add a console lock
statement. found saved count and then
the saved count constant and we return
parse int saved count. If there is no
count value in local storage, we return
the initial value we passed in. So
console log no saved count using initial
value and what is the initial value the
argument that's passed in and we return
initial value.
React will call init passing in initial
count only once when the component
mounts and use the return value as the
actual initial state. Let's import this
component into app.t jsx and test it in
the browser. So import counterwith init
from dot /counterwith init and then
invoke the component.
In the browser on the very first load we
have nothing stored in local storage. So
in the console you should see init
function called this only runs once no
saved count using initial value zero and
then the same repeats because of react's
strict mode. The UI also reflects the
same count is zero to begin with. Now
saving to local storage when the count
changes requires a different hook that
we haven't covered yet. But we can still
test the lazy initialization by manually
writing to local storage. So in the
console type local storage dot set item
the key is going to be count and the
value let's assume 42. Press enter. Then
refresh the page. Now look at the
console. Init function called this only
runs once. Found saved count. The value
is 42. on the screen the counter starts
at 42. Now if you click increment a few
times so the count is 47 and refresh
again it goes back to 42. This is
expected because we are only reading
from local storage not writing to it.
But the main thing to notice is this. If
you click the button several times
increment or decrement and look at the
console you will not see the log from
the init function again. It only runs
once on the first render. And this is
the whole point of lazy initialization.
You do the expensive or external work
once. React reuses that result on every
subsequent render. Now remember the init
argument is completely optional. Most of
the time just passing a simple value as
the second argument to use reducer is
enough. To summarize, use reducer
accepts an optional third argument, an
init function. React calls init once,
passing it the second argument. Whatever
init returns becomes the actual initial
state. The init function only runs when
the component mounts, not on every
render. It is ideal for expensive
initial computations or reading from
external sources like local storage. Now
use state and use reducer might seem
like two completely different hooks, but
they are more connected than you might
think. Something very interesting coming
up.
Github - https://github.com/gopinav/React-19-Tutorials Become a Fullstack Developer with Scrimba - https://scrimba.com/fullstack-path-c0fullstack?via=Codevolution Follow me + Twitter - https://twitter.com/CodevolutionWeb Business - codevolution.business@gmail.com React 19 useReducer Lazy Initialization