【问题标题】:How to chain API requests in useEffect() with custom hooks?如何使用自定义钩子在 useEffect() 中链接 API 请求?
【发布时间】:2021-10-21 23:51:27
【问题描述】:
  • 我正在尝试获取用户的经纬度坐标,然后使用这些坐标在 useEffect() 内部发出搜索请求
  • useResults 时,location 始终为 null 执行,这就是问题
  • useResultsfetchLocation 都单独工作,但我无法将它们链接在一起
  • 任何想法都将不胜感激,谢谢
我的代码(我正在尝试做这样的事情)
    const [fetchLocation, location, message] = useLocation()
    const [fetchResults, searchResults, isSearchError] = useResults()

    useEffect(() => {
        fetchLocation()                    // get user longitude and latitude, set longitude and latitude data into "location"
        useResults({
             location.coords.longitude, 
             location.coords.latitude })   // feed longitude and latitude data into useResults
    }, [])

useResults.js
const useResults = () => {
    const [searchResults, setSearchResults] = useState([])
    const [isSearchError, setIsSearchError] = useState(false)

    const fetchResults = async (
        searchTerm,
        { latitude, longitude }
    ) => {
        try {
            // get search data
            const response = await yelpAPI.get("/search", {
                params: {
                    limit: 50,
                    term: searchTerm,
                    latitude,
                    longitude
                }
            })
            // set search data
            setSearchResults(response.data.businesses)
        } catch (err) {
            console.log(err)
            console.log("Something went wrong in useResults.js")
            setIsSearchError(true)
        }
    }

    return [fetchResults, searchResults, isSearchError]
}

useLocation.js
const useLocation = () => {
    const [location, setLocation] = useState(null)
    const [message, setMessage] = useState(
        "Fetching user location data"
    )

    const fetchLocation = async () => {
        try {
            let { status } =
                await Location.requestForegroundPermissionsAsync()

            if (status !== "granted") {
                setErrorMsg(
                    "Permission to access location was denied"
                )
                return
            }
            // get user location data
            let locationData = await Location.getCurrentPositionAsync(
                {}
            )
            setMessage(null)
            // set user location data
            setLocation(locationData)
        } catch (err) {
            console.log(err)
            setMessage("Fetching user location failed")
        }
    }

    return [fetchLocation, location, message]
}

【问题讨论】:

    标签: reactjs react-native react-hooks use-effect


    【解决方案1】:

    由于fetchLocation 正在更新钩子的状态,看起来这些应该被分解成单独的useEffect 调用。第一个会发生一次(获取位置),第二个会在位置更改时发生。像这样的:

    useEffect(() => {
        fetchLocation();
    }, []); // empty dependency array, happens once when the component loads
    
    useEffect(() => {
        useResults({
             location.coords.longitude, 
             location.coords.latitude
        });
    }, [location]); // happens any time the location changes, which *should* only be once
    

    如果fetchLocation返回它的结果,而不仅仅是更新状态,则可能是另一种选择。例如:

    setMessage(null);
    // set user location data
    setLocation(locationData);
    return locationData; // <-- here
    

    然后,虽然状态仍然更新以供组件使用,但任何直接依赖于值的东西都可以简单地等待结果。比如:

    useEffect(async () => {
        const tempLoc = await fetchLocation();
        useResults({
             tempLoc.coords.longitude, 
             tempLoc.coords.latitude
        });
    }, []);
    

    这样您就不会多次重新渲染,而后一个操作只是使用返回的结果而不是更新的状态。

    【讨论】:

      【解决方案2】:

      你需要两个 useEffect。一个会在 mount 上运行:

        useEffect(() => {
          fetchLocation()                    // get user longitude and latitude, set longitude and latitude data into "location"
        }, [])
      

      在获取位置并具有值时将运行的一个:

        useEffect(() => {
          if (location)
            fetchResults({location.coords.longitude, 
              location.coords.latitude})                    // get user longitude and latitude, set longitude and latitude data into "location"
        }, [location])
      

      【讨论】:

        猜你喜欢
        • 2021-07-15
        • 1970-01-01
        • 2021-11-22
        • 2021-09-10
        • 1970-01-01
        • 2021-10-09
        • 2022-10-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多