如何使用 Next.js 获取用户的地理位置?

Ok *_*iro 3 geolocation reactjs next.js

我正在学习 Next.js。我想从用户那里获取纬度和经度。然后调用API。我的代码是这样的:

import Navbar from "../../comps/Navbar";
import Link from "next/link";
import Head from "next/head";
import styles from '../../styles/Mensen.module.css'
import { useEffect } from "react";
import { useState } from "react";
import Location from "../../comps/Location";
import navigator from "react";

export const getStaticProps = async (context) => {    
    const res = await fetch('https://openmensa.org/api/v2/canteens?near[lat]=' + lat+ '&near[lng]=' + long + '&near[dist]=50000');
    const data = await res.json();

    return {
      props: { mensen: data }
    }
}

const Mensen = ({mensen}) => {    
    return ( 
        <>
        <Head>
            <title>HTW Mensa | Mensen</title>
            <meta name="keywords" content="mensa"/>
        </Head>
        <Location />
        <div>
            <h1>Alle Mensen</h1>
            <p>Alle Mensen</p>
            {mensen.map(mensa => ( 
                <Link href={'/mensen/' + mensa.id} key={mensa.id}>
                    <a className={styles.single}> 
                        <h3>{ mensa.name }</h3>
                    </a>
                </Link>))}
        </div>
        </>
    );
}
 
export default Mensen;
Run Code Online (Sandbox Code Playgroud)

该 API 使用用户提供的纬度和经度来给出附近的地点。我看到有人推荐使用useEffect. 但我对此并不确定。

有人可以帮助我吗?

jul*_*ves 5

由于getStaticProps在构建时在服务器上运行,因此它无法访问用户特定的信息,例如地理位置。您必须将逻辑移至客户端。


下面是如何使用浏览器中内置的Geolocation API检索用户地理位置的示例(请注意,用户会收到通知并要求授予 API 工作权限)。

import { useEffect, useState } from 'react'
import Link from 'next/link';

const Mensen = () => {
    const [mensen, setMensen] = useState([]);
    const [location, setLocation] = useState();

    const fetchApiData = async ({ latitude, longitude }) => {
        const res = await fetch(`https://openmensa.org/api/v2/canteens?near[lat]=${latitude}&near[lng]=${longitude}&near[dist]=50000`);
        const data = await res.json();
        setMensen(data);
    };

    useEffect(() => {
        if('geolocation' in navigator) {
            // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API
            navigator.geolocation.getCurrentPosition(({ coords }) => {
                const { latitude, longitude } = coords;
                setLocation({ latitude, longitude });
            })
        }
    }, []);

    useEffect(() => {
        // Fetch data from API if `location` object is set
        if (location) {
            fetchApiData(location);
        }
    }, [location]);
    
    return ( 
        <div>
            <h1>Alle Mensen</h1>
            <p>Alle Mensen</p>
            {mensen?.length > 0 && mensen.map(mensa => ( 
                <Link href={`/mensen/${mensa.id}`} key={mensa.id}>
                    <a className={styles.single}> 
                        <h3>{mensa.name}</h3>
                    </a>
                </Link>
            ))}
        </div>
    );
};
Run Code Online (Sandbox Code Playgroud)

该组件检查 是否存在navigator.geolocation,然后尝试使用 检索用户的当前位置navigator.geolocation.getCurrentPosition()。成功后,location状态变量将被设置,从而触发对 openmensa.org API 的请求。成功获取数据后,mensen将设置状态变量,以在页面上呈现结果。