Recently am learning React hooks and am now doing a search app which have to call API then return the list movies correspond to what i type in the search box.
My code here:
useFetch.js
import { useState, useEffect } from 'react'
export const useFetch = (url, initialState) => {
const [data, setData] = useState(initialState)
const [loading, setLoading] = useState(true)
useEffect(() => {
async function fetchMovies() {
const response = await fetch(url)
const data = await response.json()
setData(data.Search)
setLoading(false)
}
fetchMovies()
}, [url])
return { data, loading }
}
App.js
import React, { useState } from 'react'
import Search from './components/Search'
import Result from './components/Result'
import Loading from './components/Loading'
import { useFetch } from './utils/useFetch'
export default function App() {
const [key, setKey] = useState('Iron man')
const onSearch = (key) => {
setKey(key)
}
const {data, loading} = useFetch(`https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`)
return (
<>
<Search handleSearch={onSearch}/>
<Loading isLoading={loading} />
<Result movies={data}/>
</>
)
}
As far as i understand after clicking button search function call API will be fired and return the result as expect. I can't put
const {data, loading} = useFetch(`https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`)
inside onSearch function. Follow the code function call API is automatically called whenever the app start and return undefined as result.
Can anyone help me out and explain why?
You are correct in your understanding of how hooks can only be called at the top level in a react component. Make the following changes and the API won't get called the first time around but will get called subsequently.
generateUrl
logic outside the component:function generateUrl(key) {
return `https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`
}
function MyComponent() {
const [url, setUrl] = React.useState('');
//...
}
url
presence in useFetch
hook by wrapping fetchMovies()
call in an if condition. This way, API won't trigger since default value of url is empty.import { useState, useEffect } from 'react'
export const useFetch = (url, initialState) => {
const [data, setData] = useState(initialState)
const [loading, setLoading] = useState(true)
useEffect(() => {
async function fetchMovies() {
const response = await fetch(url)
const data = await response.json()
setData(data.Search)
setLoading(false)
}
if(url) {
fetchMovies()
}
}, [url])
return { data, loading }
}
onSearch
const onSearch = (key) => {
setUrl(generateUrl(key))
}
也许您可以通过以下方式公开setUrl
:
return { data, loading, onSearch: (key) => setUrl(generateUrl(key)) }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.