1

I have a following return from my component

      <div className="content page-with-map" >
        <div className='route-editor'>
          <Loader loading={routeSectionsLoadingList}/>
          {this.renderRouteSectionsList()}
          <div className='route-map-block'>
            <MapComponent className='route-map'>
              <Pane name='RouteSections' style={{ zIndex: 300 }}>
                <RouteSectionsLayer
                  isAdd={isAdd}
                  isEdit={isEdit}
                  linesData={routeSectionsFeaturesList}
                  selectedLine={selectedSection}
                  setSelectedLine={this.handleSelectSection}
                  hoveredLine={hoveredSection}
                  onMouseOverLine={this.onMouseOver}
                  onMouseOutLine={this.onMouseOut}
                />
              </Pane>
            </MapComponent>
          </div>
        </div>
      </div>
    );

and here is my MapComponent, where i take children and add some custom props. Also rendering map on condition of higher div added to the DOM:

  const cityBounds = CITY_BOUNDS;

  // State
  const [bounds, setBounds] = useState(cityBounds);
  const [renderMap, setRenderMap] = useState(false);
  const [zoom, setZoom] = useState();

  const leafletContainerRef = useRef(null);

  useEffect(() => {
    if (leafletContainerRef.current) {
      setRenderMap(true);
    }
  }, [leafletContainerRef.current]);


  const onViewportChanged = (viewport) => {
    const { zoom } = viewport;
    setZoom(zoom);
  };

  const onBoundsChanged = (bounds) => {
    setBounds(bounds);
  };

  const {
    className,
    children,
  } = props;
  let customProps = {};
  return (
    <div className={classNames('leaflet-container', className)} ref={leafletContainerRef}>
      {renderMap ?
        <MapContainer
          bounds={bounds}
          doubleClickZoom={false}
          crs={L.CRS.EPSG3395}
          onViewportChanged={onViewportChanged}
        >
          <TileLayer
            url="https://vec{s}.maps.yandex.net/tiles?l=map&v=20.07.01-0&x={x}&y={y}&z={z}&scale=1&lang=ru_RU"
            subdomains={['01', '02', '03', '04']}
            attribution='<a http="yandex.ru" target="_blank">Яндекс</a>'
          />
          {React.Children.map(children, child => {
            customProps = { ...customProps, onBoundsChanged: onBoundsChanged, bounds: bounds };
            return React.cloneElement(child, customProps);
          })}
        </MapContainer>
        : null}
    </div>
  );
}

And also RouteSectionsLayer component:

export default function RouteSectionsLayer(props) {
  const { isEdit = false, selectedLine } = props;

  const getLines = () => {
    const { onMouseOverLine = () => {}, onMouseOutLine = () => {}, linesData = [] } = props;
    return linesData && linesData.length ?
      linesData.map((lineFeature, i) => {
        const lineIndex = i;
        return <Polyline
          key={hash(lineIndex)}
          pane={'RouteSections'}
          positions={lineFeature.geometry
          && lineFeature.geometry.coordinates
          && lineFeature.geometry.coordinates.map(line => line.map(vertex => vertex.map(coordinate => +coordinate)))}
          attribution={`${i}`}
          lineIndex={lineIndex}
          pathOptions={{
            color: 'black',
            weight: 5,
          }}
        />;
      })
      : null;
  };

  return (
    getLines()
  );
}

While rendering i get "Uncaught TypeError: Cannot read property 'appendChild' of undefined". What am i doing wrong?

UPDATE: I tried to rewrote RouteSectionsLayer following core architecture example from docs, now it looks like this:

export default function RouteSectionsLayer(props) {

  const leafletContext = useLeafletContext();

  const getLinesData = () => {
    const { input, linesData = [] } = props;
    if (input && input.value) {
      return input.value;
    }
    return linesData;
  };

  useEffect(() => {
    const container = leafletContext.layerContainer || leafletContext.map;
    const linesData = getLinesData();
    const polyLinesInstances = linesData && linesData.length ?
      linesData.map((lineFeature, lineIndex) => {
        const latlngs = lineFeature.geometry && coordsToNumbers(lineFeature.geometry.coordinates);
        const layerOptions = {
          attribution: `${lineIndex}`,
          pane: 'RouteSections'
        };
        const pathOptions = normalRouteSectionStylePathOptions;
        const polyLineOptions = {
          lineIndex: { lineIndex },
          ...layerOptions,
          ...pathOptions
        };
        return new L.Polyline(latlngs, polyLineOptions)
      })
      : [];
    const layerGroupInstance = new L.LayerGroup(polyLinesInstances);
    container.addLayer(layerGroupInstance);
    return () => {
      container.removeLayer(layerGroupInstance);
    };
  });

const coordsToNumbers = (lineCoordinates) => {
  return lineCoordinates && lineCoordinates.length ?
    lineCoordinates.map(line => line.map(vertex => vertex.map(coordinate => +coordinate)))
    : null;
};

And the error is still here

Error stack

enter image description here

  • Can you give us some more detail about the error, maybe the whole error with the stack trace? – Seth Lutske Feb 16 '21 at 18:03
  • Thx for reply, i almost lost hope) I updated the question and attached screenshots of the piece of error stack. Hope it will be enough – Artem Vokov Feb 17 '21 at 07:30

1 Answers1

1

well, i found my mistake. In re-wrote RouteSectionsLayer i deleted pane in the options of the polyline:

const layerOptions = {
   attribution: `${lineIndex}`,
   pane: 'RouteSections' // <-- i deleted this. 
};

It seams that the pane 'RouteSections' i created as a child of MapComponent was not found.