I am trying to make an API call inside a functional component, based on a form submission:
const SearchForm = () => {
const [keywords, setKeywords] = useState('')
const [fetchedData, setFetchedData] = useState('')
const handleSubmit = (e) => {
e.preventDefault();
useEffect(() => {
async function fetchData() {
const {data} = await axios.post('http://127.0.0.1:8000/api/posts/', keywords)
setFetchedData(data);
}
fetchData()
})
}
return (
<div>
<form onSubmit={ handleSubmit }>
<div className='input-field'>
<input placeholder="Search whatever you wish"
type="text"
value={keywords}
onChange={(e) => setKeywords(e.target.value)}
/>
</div>
</form>
</div>
)
}
However when I try this, the following error shows up:
React Hook "useEffect" is called in function "handleSubmit" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
How do I carry this out?
The useEffect Hook is built in a way that we can return a function inside it and this return function is where the cleanup happens. The cleanup function prevents memory leaks and removes some unnecessary and unwanted behaviors.
By default useEffect will trigger anytime an update happens to the React component. This means if the component receives new props from its parent component or even when you change the state locally, the effect will run again.
To trigger the useEffect hook before unmounting the component from the screen, we can return a function from the callback function. The function returned by the callback will be executed before that component is unmounted.
Side Effect Runs Only Once After Initial Render You do not want to make this API call again. You can pass an empty array as the second argument to the useEffect hook to tackle this use case. useEffect(() => { // Side Effect }, []); In this case, the side effect runs only once after the initial render of the component.
Because it is not how useEffect used for. You don't need to call it inside handler either.
From the documentation :
Only Call Hooks from React Functions Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page). By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.
If you want fetch data onload of your functional component, you may use useEffect like this :
useEffect(() => {
fetchData()
}, [])
And you want your fetch call to be triggered with button click :
const handleSubmit = e => {
e.preventDefault()
fetchData()
}
So whole code will look like :
const SearchForm = () => {
const [keywords, setKeywords] = useState('')
const [fetchedData, setFetchedData] = useState('')
async function fetchData() {
const { data } = await axios.post(
'http://127.0.0.1:8000/api/posts/',
keywords
)
setFetchedData(data)
}
useEffect(() => {
fetchData()
}, [])
const handleSubmit = e => {
e.preventDefault()
fetchData()
}
return (
<div>
<form onSubmit={handleSubmit}>
<div className="input-field">
<input
placeholder="Search whatever you wish"
type="text"
value={keywords}
onChange={e => setKeywords(e.target.value)}
/>
</div>
</form>
</div>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With