Reputation: 1056
I have a button that is supposed to submit a form to an API. I am getting an error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function...
My entire code is here:
function SubmitButton(props) {
function SendData(url) {
const [data, setData] = useState([]);
const eta = document.getElementById('eta_value')
async function getData() {
const options ={
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({
name:'26',
eta:'30',
})
}
const response = await fetch(url, options)
.then(response =>{
console.log(response.status);
});
}
useEffect(() => {//check this out
getData();
}, []);
};
const title = props.title;
//const onSubmit = {SendData}
return(
<div id={title}>
<Button
onClick={() => SendData("http://XXX.X.X.X:XXXX/api/")}
variant="contained"
color="primary">
</Button>
</div>
)
}
export default SubmitButton
It shows the error originates at:
function SendData(url) {
const [data, setData] = useState([]);
const eta = document.getElementById('eta_value')
async function getData() {
Which is called by onClick. I troubleshooted for several days, but cannot figure out why I am breaking the rules of hooks.
Upvotes: 0
Views: 1515
Reputation: 2036
Your hooks calls must be on the top level of your render function(react hook rules), not inside of SendData function
function SubmitButton(props) {
const [data, setData] = useState([]);
function SendData(url) {
const eta = document.getElementById('eta_value')
async function getData() {
const options ={
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({
name:'26',
eta:'30',
})
}
const response = await fetch(url, options)
.then(response =>{
console.log(response.status);
});
}
};
useEffect(() => {
getData();
}, []);
const title = props.title;
//const onSubmit = {SendData}
return(
<div id={title}>
<Button
onClick={() => SendData("http://XXX.X.X.X:XXXX/api/")}
variant="contained"
color="primary">
</Button>
</div>
)
}
export default SubmitButton
And you'd better move code that fetches data outside of render function, for the sake of readability.
Upvotes: 1
Reputation: 211
The problem is that you are using the useState
hook within a nested function (your sendData()
function).
As the Rules of Hooks documentation reads:
Only Call Hooks at the Top Level
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls. (If you’re curious, we’ll explain this in depth below.)
To fix this, move your const [data, setData] = useState([]);
statement and the useEffect()
hook to the top level of your functional component.
Hope this helps.
Upvotes: 4