You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Leaflet从.env文件每秒更新Marker位置的技术问题

解决方案

核心问题分析

你遇到的仅能获取6次数据的问题,大概率是浏览器缓存了data.env的请求结果,后续请求直接读取缓存而非从Arduino服务器获取最新内容。另外原代码中还有坐标解析、组件渲染逻辑的小问题需要调整。

具体修复步骤

1. 禁用请求缓存

在fetch请求中添加时间戳参数,强制浏览器每次都从服务器获取最新文件:

fetch(`${textfile}?t=${Date.now()}`)

也可以通过请求头直接禁用缓存:

fetch(textfile, {
  headers: {
    'Cache-Control': 'no-cache, no-store, must-revalidate',
    'Pragma': 'no-cache',
    'Expires': '0'
  }
})

2. 优化坐标解析与组件逻辑

  • 把data.env的格式改成便于解析的结构,比如:LAT=43.123456,LNG=11.654321
  • 分离坐标解析逻辑,避免每次渲染重复处理
  • 确保标记组件仅在坐标变化时更新

3. 修正标记组件代码

修改后的完整组件(建议重命名为GpsMarker更清晰):

import React, { useState, useEffect } from "react";
import { Marker, Popup } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import L from 'leaflet';

import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

let DefaultIcon = L.icon({
    iconUrl: icon,
    shadowUrl: iconShadow
});

L.Marker.prototype.options.icon = DefaultIcon;

function GpsMarker() {
    const [position, setPosition] = useState(null);

    useEffect(() => {
        const fetchCoordinates = async () => {
            try {
                // 添加时间戳避免缓存
                const response = await fetch(`./data.env?t=${Date.now()}`);
                const textContent = await response.text();
                
                // 解析.env格式的内容
                const coords = textContent.split(',').reduce((acc, item) => {
                    const [key, value] = item.split('=');
                    acc[key.toLowerCase()] = parseFloat(value);
                    return acc;
                }, {});
                
                if (coords.lat && coords.lng) {
                    setPosition([coords.lat, coords.lng]);
                }
            } catch (error) {
                console.error('获取坐标失败:', error);
            }
        };

        // 立即执行一次,避免初始等待
        fetchCoordinates();
        // 设置2秒间隔更新
        const interval = setInterval(fetchCoordinates, 2000);

        return () => clearInterval(interval);
    }, []);

    // 只有当position存在时才渲染标记
    if (!position) return null;

    return (
        <Marker position={position}>
            <Popup>
                当前位置:<br />
                纬度:{position[0].toFixed(6)}<br />
                经度:{position[1].toFixed(6)}
            </Popup>
        </Marker>
    );
}

export default GpsMarker;

4. 调整主App组件

替换原有的Interval组件为新的GpsMarker:

// ... 其他导入
import GpsMarker from "./GpsMarker";

function App() {
  const latitude = 43.000;
  const longitude = 11.000;
  const mapRef = useRef(null);

  return (
    <HashRouter>
      <MapContainer center={[latitude, longitude]} zoom={13} ref={mapRef} style={{ height: "99vh", width: "100vw" }}>
        <GpsMarker />
        <GeoJSON data={CTR} />
      </MapContainer>
    </HashRouter >
  );
}

export default App;

额外注意事项

  • 确保Arduino写入data.env的格式正确,避免解析错误
  • 若Arduino的HTTP服务器支持,建议用API接口返回JSON格式坐标,比解析.env文件更可靠
  • 可根据实际情况调整setInterval的时间间隔,避免过于频繁的请求给Arduino带来负担

内容的提问来源于stack exchange,提问作者Sebastian Schweizer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 22:00:14