单击事件后如何触发函数 useEffect?
How to fire the function useEffect after clicking event?
最近正在学习 React hooks,现在正在做一个搜索应用程序,它必须调用 API 然后 return 电影列表与我在搜索框中输入的内容相对应。
我的代码在这里:
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}/>
</>
)
}
据我所知,点击按钮后搜索函数调用 API 将被触发,return 结果如预期。我放不下
const {data, loading} = useFetch(`https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`)
在 onSearch 函数中。遵循代码函数调用 API 会在应用程序启动时自动调用,结果 return 未定义。
谁能帮我解释一下为什么?
你对如何只能在 React 组件的顶层调用 hooks 的理解是正确的。进行以下更改,API 不会第一次被调用,但随后会被调用。
- 使用url状态变量并在组件外部提取
generateUrl
逻辑:
function generateUrl(key) {
return `https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`
}
function MyComponent() {
const [url, setUrl] = React.useState('');
//...
}
- 通过在 if 条件中包装
fetchMovies()
调用来检查 url
是否存在于 useFetch
挂钩中。这样,API 不会触发,因为 url 的默认值为空。
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)) }
最近正在学习 React hooks,现在正在做一个搜索应用程序,它必须调用 API 然后 return 电影列表与我在搜索框中输入的内容相对应。
我的代码在这里:
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}/>
</>
)
}
据我所知,点击按钮后搜索函数调用 API 将被触发,return 结果如预期。我放不下
const {data, loading} = useFetch(`https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`)
在 onSearch 函数中。遵循代码函数调用 API 会在应用程序启动时自动调用,结果 return 未定义。
谁能帮我解释一下为什么?
你对如何只能在 React 组件的顶层调用 hooks 的理解是正确的。进行以下更改,API 不会第一次被调用,但随后会被调用。
- 使用url状态变量并在组件外部提取
generateUrl
逻辑:
function generateUrl(key) {
return `https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`
}
function MyComponent() {
const [url, setUrl] = React.useState('');
//...
}
- 通过在 if 条件中包装
fetchMovies()
调用来检查url
是否存在于useFetch
挂钩中。这样,API 不会触发,因为 url 的默认值为空。
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)) }