简体   繁体   English

单击事件后如何触发函数useEffect?

[英]How to fire the function useEffect after clicking event?

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.最近正在学习 React 钩子,现在正在做一个搜索应用程序,它必须调用 API,然后返回与我在搜索框中键入的内容相对应的列表电影。

My code here:我的代码在这里:

useFetch.js使用Fetch.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应用程序.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.据我了解,单击按钮搜索函数调用 API 将被触发并按预期返回结果。 I can't put我放不下

const {data, loading} = useFetch(`https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`)

inside onSearch function.onSearch函数中。 Follow the code function call API is automatically called whenever the app start and return undefined as result.遵循代码 函数调用 API 会在应用程序启动时自动调用并返回 undefined 作为结果。

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.进行以下更改,API 不会在第一次被调用,但会在随后被调用。

  1. Use url state variable and extract generateUrl logic outside the component:使用 url 状态变量并在组件外部提取generateUrl逻辑:
function generateUrl(key) {
  return `https://www.omdbapi.com/?s=${key}&apikey=${API_KEY}`
}

function MyComponent() {
  const [url, setUrl] = React.useState('');
  //...
}
  1. Check for url presence in useFetch hook by wrapping fetchMovies() call in an if condition.通过在 if 条件中包装fetchMovies()调用来检查useFetch钩子中的url是否存在。 This way, API won't trigger since default value of url is empty.这样,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 }
}
  1. Finally, modify onSearch最后,修改onSearch
const onSearch = (key) => {
   setUrl(generateUrl(key))
}

也许您可以通过以下方式公开setUrl

return { data, loading, onSearch: (key) => setUrl(generateUrl(key)) }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM