I am trying to use the useState
hook in React to set an initial value as an empty function, but when I try to console.log
the state variable, I get undefined.
Here is the code I am using:
import {useState} from 'react';
function MyComponent() {
const [callback, setCallback] = useState(() => {});
console.log(callback);
return <div>My component</div>;
}
I have also tried using the useEffect
hook to update the state, but I am still getting undefined
.
I am new to React and I am not sure what I am doing wrong. Can someone please help me understand why I am getting undefined and how I can fix it?
CodePudding user response:
Passing a function to useState
indicates lazy initialization - the function gets invoked once when the component mounts, and the value returned from the function determines the initial value.
If you want state to be a function, you'll need to have a function that returns a function.
const [callback, setCallback] = useState(() => () => {});
But it rarely makes sense for state to be a function. Use something more appropriate like useCallback
, or just declare a plain function.
const callback = () => {
// ...
};
CodePudding user response:
useState
can optionally use a function to produce the initial value as a performance enhancement. So it's seeing your function that returns undefined
as an initializer.
Try
// ,----- this is a function that returns a
// v function that does nothing
useState(() => () => {})
CodePudding user response:
If you want to use useState's initial value as a function, you need to use Lazy Initial State:
const [callback, setCallback] = useState(functionName())
So if you do:
function functionName(){
return 'some computations'
}
Now if you log, functionName
will return some computations as a result(You can return anything you want).
CodePudding user response:
The argument you pass to useState is the initial value that React holds on to for every render until that state needs to change (through the "set function" which is the second value returned from the useState hook.)
We don't typically use functions as that initial value - but it can be done as explained in the other answers!
Since we're using functions (the useState hook) inside of functions (your component) we're creating closures that are going to be re-created every render. Now there's a serious issue with recreating things every render: the component can't "remember" anything when the closure gets recreated! This is why we have state. It allows the component to remember what previously exists.
We use the useEffect hook to "step outside" of React and go sync to an external system. Often we useEffect to retrieve some data:
import React, {useState, useEffect} from 'react';
function MyComponent() {
const [data, setData] = useState();
useEffect(() => {
async function retrieveData(){
const myData = await fetch(https://whatever...)
// now pass the data to the set state function
setData(myData)
}
}, [])
return <div>My component</div>;
}
I highly advise you to read through the new React docs here They do an excellent job of walking you through everything!