0

我想在 react-leaflet 中绘制一个多边形并将创建的图层发布到 API。除此之外,还有不同的任务保存在数据状态中。当前活动的任务在 activeTask 中。data 和 activeTask 都由上下文提供。每次发布图层时,我都想添加当前活动任务的 taskId。问题是:当我发布图层和taskId时,taskId为空。所以在第一个console.log(称为“activeTask 1”)中,activeTask 不是空的,所以一切都很好。但是在第二个console.log(称为“activeTask 2”)中,activeTask 是空的。如何访问 activeTask 以将其 _id 发布到 API?

import React, { useContext } from 'react';
import axios from 'axios';

import { MapContainer, TileLayer, Marker, Popup, FeatureGroup, GeoJSON } from 'react-leaflet';
import { EditControl } from 'react-leaflet-draw';
import 'leaflet/dist/leaflet.css';
import 'leaflet-draw/dist/leaflet.draw.css';

import { DataContext } from './DataContext';


const LeafletComponent = () => {
    const { dataContext, activeTaskContext } = useContext(DataContext);
    const [activeTask, setActiveTask] = activeTaskContext;
    const [data, setData] = dataContext;
    const position = [51.505, -0.09]
    let listAreas = [];
    for (let i = 0; i < data.length; i++) {
        if ("taskArea" in data[i]) {
            for (let j = 0; j < data[i].taskArea.length; j++) {
                if ("areaBoundaries" in data[i].taskArea[j]) {
                    listAreas.push(<GeoJSON key={data[i].taskArea[j]._id} data={JSON.parse(data[i].taskArea[j].areaBoundaries)} />);
                }
            }
        }
    }

    console.log("activeTask 1");
    console.log(activeTask);

    const _onCreated = async (e) => {
        console.log("activeTask 2");
        console.log(activeTask);// <-- this activeTask is empty
        const layer = e.layer;
        const geoj = layer.toGeoJSON();
        const postData = {
            taskId: activeTask._id,// <-- this activeTask is empty
            areaBoundaries: JSON.stringify(geoj)
        }
        try {
            const response = await axios.post('http://localhost:3333/createarea', postData);
            // do something with response
        } catch (error) {
            console.log(error);
        }
    };

    return (
        <MapContainer center={position} zoom={13} scrollWheelZoom={true}>
            <FeatureGroup>
                <EditControl position="topright" onCreated={_onCreated} draw={{
                    marker: false,
                    circle: false,
                    circlemarker: false,
                    rectangle: true,
                    polyline: false,
                    polygon: true
                }} />
            </FeatureGroup>
            <TileLayer
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
            {listAreas}
        </MapContainer>
    )
}

export default LeafletComponent;
4

1 回答 1

0

您是否尝试将 _onCreated 实现为依赖于 activeTask 的 useCallback。像这样

const _onCreated = React.useCallback(async (e) => {
       //... 
}, [activeTask]);

反应 -> 使用回调

您还可以考虑将 for 循环放入 useMemo

const listAreas = React.useMemo(() => {
...
}, [data])

甚至可以使用像ramdajs这样的东西来简化你的嵌套循环

pipe(
  map(x => x.taskArea),  
  flatten,
  filter(x => x && x.areaBoundaries)
  map(x => (<GeoJSON key... />))
)(data)
于 2021-09-14T15:08:30.817 回答