Reputation: 2615
I have a function that gets some data when it is initiated. This can be done by a click even on a button, e.g.:
<button type="button" onClick={fetchData}>Get data</button>
Basically it is just a function given by:
function fetchData(e) {
e.preventDefault();
<something POST to get data>
}
All of this is working as intended. However, the data is only fetched when the button is clicked. I would like for the data to be fetched on load as well so there is actually some data presented before the button is clicked.
I thought I could just say:
useEffect(() => {
fetchData()
}, [])
But that doesn't seem to work. However, if I take everything inside the function, and replace it with the fetchData()
in the useEffect
, then it works. But I don't feel like changing stuff twice every time the function needs updates etc.
So what am I doing wrong ?
Upvotes: 0
Views: 62
Reputation: 66123
That is because when you're calling fetchData()
in useEffect
, no argument is being provided to the function. Yet in the function you are expecting the first argument to be present and calling it with e.preventDefault()
. Since e
will be undefined, attempting to access a key/property inside undefined
will throw an error.
There are two solutions:
e
when it is not undefinedBy first checking if e
is null or undefined, we can prevent attempting to access a key/property on it:
function fetchData(e) {
e?.preventDefault();
// Additional fetching logic
}
If you want to also support browsers that do not support optional chaining, then using the logical AND operand (&&
) to perform lazy evaluation / short-circuiting will also work:
function fetchData(e) {
e && e.preventDefault();
// Additional fetching logic
}
Remove e
from your fetchData function completely:
function fetchData() {
// Additional fetching logic
}
...and prevent the default event at the level of the click handler:
const onClick = (e) => {
e.preventDefault();
fetchData();
}
<button type="button" onClick={onClick}>Get data</button>
Upvotes: 2