How to rewrite JS Progressbar.js object to React component - javascript

I play with React for few days, everything seemed fairly easily, until I got stuck with rewriting this JS object as a React component.
This is JsFiddle Example with JS object example. How to go about rewriting this as React component?
This is what I was trying:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import ProgressBar from 'progressbar.js';
class Circle extends Component{
componentDidMount() {
this._create(this.props);
}
_create(props) {
var container = ReactDOM.findDOMNode(this.refs.progressBar);
container.animate(props.progress);
}
render() {
return <div ref="progressBar"></div>;
}
}
Circle.defaultProps = {
options: {},
progress: 1.0,
}
export default Circle;

Here is a example of loading circle,
but it is NOT modified from the code above.
Instead, I use SVG, strokeDashArray and strokeDashOffset
CODE
import React from 'react';
const styles = {
svg :{
position:'fixed',
width:'100%',
height:'100%',
position:'fixed',
top:'0', left:'0',
background:'rgba(240,240,240,1)',
},
circle : {
strokeDasharray : '300',
transition : 'all .4s ease-in',
},
}
export default class Loading extends React.Component {
constructor(props){
super(props);
let screenSize = this._calculateDevice();
this.state = { offset:600,
cx:screenSize.width/2,
cy:screenSize.height/2,
r:50,
}
this._unmount = this._unmount.bind(this);
}
_calculateDevice() {
let width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
let height = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
return {width, height}
}
componentDidMount (){
this.interval = setInterval(() => {
const offset = this.state.offset - 50;
this.setState({offset: offset });
},200);
}
componentWillUnmount() {
clearInterval(this.interval);
}
_unmount () {
this.setState({loaded:true});
}
_circlePath (){
let d = `M${this.state.cx},${this.state.cy}a${this.state.r},${this.state.r} 0 1,0 100,0a${this.state.r},${this.state.r} 0 1,0 -100,0`;
return d
}
render (){
let d = this._circlePath();
let style = Object.assign({}, styles.circle, {'strokeDashoffset':this.state.offset});
let svgStyle = styles.svg;
return(
<svg style={svgStyle}>
<path
stroke = "#AAA"
strokeWidth = "5px"
fill = "none"
d = {d}
/>
<path
style = {style}
stroke = "#D22"
strokeWidth = "5px"
fill = "none"
d = {d}
/>
</svg>
)
}
}
Briefly explain
componentDidMount (){
this.interval = setInterval(() => {
const offset = this.state.offset - 50;
this.setState({offset: offset });
},200);
}
the function in the setInterval will update the offset
and will also create new path.
_circlePath (){
let d = `M${this.state.cx},${this.state.cy}a${this.state.r},${this.state.r} 0 1,0 100,0a${this.state.r},${this.state.r} 0 1,0 -100,0`;
return d
}
and this function will create the path which decide how the circle looks like in svg.
So we can use the changing of path to implement the effect of spinning circle
NOTICE
Due to the setInterval function
we need to remember to clear the interval before the component unmount
to avoid crash of setInterval on a component that doesn't exist.

Related

How can I split letters and animate its position property based on some condition

I am trying to make an alphabet soup like in this CodePen using react.
The problem i'm facing at present is that I want to display the split result inside my main component. At present i'm able to animate its CSS property a bit but unable to display the split result. A hint on how to go ahead will be really helpful.
My code is as below:
import React, {useState} from "react";
export default function SlideCard(props) {
//const [ split, setSplitted ] = useState([]);
//console.log(split);
const { id, idx, title } = props;
const inputText = title;
const scatter = {
position: "absolute",
top: "",
left: "",
zIndex: "initial",
transition: "left 2s, top 2s"
};
if (id !== idx) {
//split if not active//
inputText.split("").map((letter) => {
var randLeft = Math.floor(Math.random() * 400);
var randTop = Math.floor(Math.random() * 200);
scatter.top = +randTop + "px";
scatter.left = +randLeft + "px";
console.log(letter); //How can I use this split inside the main component
return letter;
//return setSplitted(letter);
// I tried setting it to a useState, but don't know why it is giving me an infinite loop.
});
} else {
scatter.top = "50%";
scatter.left = "50%";
}
//main component
return <div style={scatter}>{inputText}</div>;
}
file=/src/components/SlideCard.jsx

How to render the actual value of the scroll percentage?

I have this piece of code
import React from 'react'
const App = () => {
function getScrollPercent() {
var h = document.documentElement,
b = document.body,
st = 'scrollTop',
sh = 'scrollHeight';
var scrollPercent = Math.round((h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100);
//get the percentage of scroll
return (isNaN(scrollPercent) ? '' : scrollPercent)
}
return (
<p>{`${getScrollPercent()}%`}</p>
)
the problem is when I scroll the scrollPercent doesn't refresh in real time but only when the scroll stop, so scrollPercent can pass from 0% to 100% and not display all the numbers between 0 and 100, so the question is how can I modify my piece of code to display the actual value of scrollPercent even when I scroll
You will need to use a useEffect to add an event listener that will listen for the scroll event. Then, you can register a function that will re-calculate the scroll position when the user scrolls up or down the page.
import React, { useEffect, useState } from "react";
function getScrollPercent() {
var h = document.documentElement,
b = document.body,
st = "scrollTop",
sh = "scrollHeight";
var scrollPercent = Math.round(
((h[st] || b[st]) / ((h[sh] || b[sh]) - h.clientHeight)) * 100
);
//get the percentage of scroll
return isNaN(scrollPercent) ? "" : scrollPercent;
}
const App = () => {
// this represents the current calculated scroll percentage
// maybe initialize this to something other than empty string
const [scrollPercentage, setScrollPercentage] = useState("");
useEffect(() => {
function handleScroll() {
const newScrollPercentage = getScrollPercent();
// calculate and set the new scroll percentage
setScrollPercentage(newScrollPercentage);
}
window.addEventListener("scroll", handleScroll, true);
// clean up event listener when component unmounts
return () => {
window.removeEventListener('scroll', handleScroll, true);
}
}, []);
// this contains extra styling to demo, so that you can see the
// scroll value change when scrolling, probably remove these style props
return (
<div style={{ height: "3000px" }}>
<p style={{ position: "fixed" }}>{`${scrollPercentage}%`}</p>
</div>
);
};
export default App;
Codesandbox Link to example: Codesandbox
You need to use window.addEventListener to reach what you want.
import React from "react";
const App = () => {
const [scroll, setScroll] = React.useState("");
function getScrollPercent() {
var h = document.documentElement,
b = document.body,
st = "scrollTop",
sh = "scrollHeight";
var scrollPercent = Math.round(
((h[st] || b[st]) / ((h[sh] || b[sh]) - h.clientHeight)) * 100
);
setScroll(isNaN(scrollPercent) ? "" : scrollPercent);
}
React.useEffect(() => {
window.addEventListener("scroll", getScrollPercent);
return () => {
window.removeEventListener("scroll", getScrollPercent);
};
}, []);
return (
<div style={{ height: "1000px" }}>
<p style={{ position: "fixed" }}>{`${scroll}%`}</p>
</div>
);
};
export default App;
Codesanbox Link: https://codesandbox.io/s/unruffled-field-3l3z8?file=/src/App.js:0-664

Custom useOneLineText React Hook that adjusts font size and always keeps text on one line

I'm trying to create a custom hook that will keep the text on one line, this is what I've got so far:
import { useEffect, useState, useRef } from "react";
export default function useOneLineText(initialFontSize, text) {
const containerRef = useRef(null);
const [adjustedFontSize, setAdjustedFontSize] = useState(initialFontSize);
useEffect(() => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const containerWidth = containerRef.current.getBoundingClientRect().width;
let currentFontSize = initialFontSize;
do {
ctx.font = `${currentFontSize}px "Lato"`;
currentFontSize -= 1;
} while (containerWidth < ctx.measureText(text).width);
setAdjustedFontSize(currentFontSize);
}, []);
return { containerRef, adjustedFontSize, text };
}
And the usage:
import React, { useState } from "react";
import "./style.css";
import useOneLineText from "./useOneLineText";
const initialFontSize = 32;
export default function App() {
const [shortText, setShortText] = useState("Hello Peaceful World!");
const { containerRef, adjustedFontSize, text } = useOneLineText(
initialFontSize,
shortText
);
return (
<div>
<h1
ref={containerRef}
style={{ width: "100px", fontSize: `${adjustedFontSize}px` }}
>
{text}
</h1>
<h1 style={{ width: "100px", fontSize: `${initialFontSize}px` }}>
Hello Cruel World!
</h1>
<button onClick={() => setShortText("Hello World!")}>Remove Peace</button>
</div>
);
}
I was wondering why is my font not updating when trying to change the text with the Remove Peace button. I'm also not sure if looping inside useEffect and decreasing the font size by 1 is the best way to go, is it possible to calculate the adjusted font size without the loop? Here is my working example.
Well, your code already works as it seems. From your example, the initial font size of 32px changes to a 10px on mount. Also, your effect only runs on mount.
Without removing the word, it would also already satisfy the containerWidth < ctx.measureText(text).width.
If you want the effect to happen when the containerWidth or textWidth changes, then you can add more states and add them on your useEffect dependency list.
const [container, setContainerState] = useState(null);
const [textWidth, setTextWidth] = useState(null);
useEffect(() => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const refWidth = containerRef.current.getBoundingClientRect().width;
let currentFontSize = initialFontSize;
if (
textWidth !== ctx.measureText(text).width ||
containerWidth !== refWidth
) {
do {
ctx.font = `${currentFontSize}px "Lato"`;
currentFontSize -= 1;
} while (refWidth < ctx.measureText(text).width);
setContainerWidth(containerWidth);
setTextWidth(textWidth);
setAdjustedFontSize(currentFontSize);
}
}, [textWidth, containerWidth]);
For a faster adjusting of font size, you can check this answer out from a jquery question that uses binary search to help you find the right width quicker?
Auto-size dynamic text

Mapbox example as a React component

I am trying to use this fiddle code from Mapbox in my react app. Official code here
So far, this is my code, I am getting this error TypeError: Cannot set property 'accessToken' of undefined I am new to React so having a hard time converting this js code. Any resources/codelinks are appreciated for reference. And how can I make mapbox work as a react component.
import React, { useEffect } from "react";
// import * as d3 from 'd33';
import './StreamGraph.css';
// import 'https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.js';
// import 'https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css';
// import 'https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js';
// import 'https://code.jquery.com/jquery-3.5.1.js';
// import 'https://api.mapbox.com/mapbox.js/plugins/arc.js/v0.1.0/arc.js';
// import 'https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/leaflet.markercluster.js';
// import 'https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/MarkerCluster.css';
// import 'https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/MarkerCluster.Default.css';
// import mapbox from 'mapbox';
import 'mapbox';
import 'leaflet';
import arc from 'arc';
import largeAirports from '../data/large_airports_only.csv';
import 'mapbox/lib/mapbox.js';
import 'jquery/dist/jquery.min.js';
import 'jquery/src/ajax.js';
import 'ajax/lib/ajax.js';
import 'arc/arc.js';
import 'jquery/src/jquery.js';
import 'mapbox/dist/mapbox-sdk.min.js';
import L from 'leaflet';
import 'leaflet.markercluster/dist/leaflet.markercluster.js';
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
// import * from 'jquery';
// setting up via node
// var MapboxClient = require('mapbox');
// var client = new MapboxClient('pk.eyJ1Ijoic2FueWFzaW4iLCJhIjoiY2tnbzA2aW9mMGI4cTJybnFvOTVzYm84aCJ9.voOP8PnCpZrEsilFflPswg');
function Mapbox(props) {
useEffect(() => {
console.log(largeAirports);
// feb map for now
var pairs = [[[47.539123535, -122.30667114299999], [47.539238364, -122.30649508]], [[38.690728656, -121.60168457], [47.54095459, -122.311683655]], [[49.297393799, -123.105046199], [48.41784668, -123.388718825]], [[25.065261065, 121.22915591799999], [22.31350708, 113.906000311]], [[34.422586732, 135.237007141], [25.067138672, 121.23148600299999]], [[49.18676861300001, -123.16721866], [49.17910766600001, -123.14927321200001]], [[22.298858643000003, 113.90620006200001], [25.073966333, 121.21734043299999]]]
// declaring for the purpose of checking mapbox in react
var ident_lat = {"KLAX": 47.539123535}
var ident_lon = {"KLAX": -122.30252}
var origin_lat = {"KLAX": -122.30252}
var origin_lon = {"KLAX": -122.30252}
var dest_lat = {"KLAX": -122.30252}
var dest_lon = {"KLAX": -122.30252}
var container = L.DomUtil.get('map');
if(container != null){
container._leaflet_id = null;
}
L.mapbox.accessToken = 'pk.eyJ1Ijoic2FueWFzaW4iLCJhIjoiY2tnbzA2aW9mMGI4cTJybnFvOTVzYm84aCJ9.voOP8PnCpZrEsilFflPswg';
// Animation is non-geographical - lines interpolate in the same amount of time regardless of trip length.
// Show the whole world in this first view.
var map = L.mapbox.map('map')
.setView([20, 0], 2)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/satellite-v9'));
var credits = L.control.attribution({
prefix: ''
}).addTo(map);
// Disable drag and zoom handlers.
// Making this effect work with zooming and panning
// would require a different technique with different
// tradeoffs.
map.dragging.disable();
map.touchZoom.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
if (map.tap) map.tap.disable();
// Transform the short [lat,lng] format in our
// data into the {x, y} expected by arc.js.
function obj(ll) { return { y: ll[0], x: ll[1] }; }
// var select_id = document.getElementById('select');
// var get_value = select_id.value;
// var get_ident = name_ident.get(get_value)
// console.log("get_ident: ", get_ident);
var counter = 0;
var get_ident = undefined;
if (get_ident != undefined){
// adding marker - airport
var marker = L.marker(new L.LatLng(ident_lat.get(get_ident), ident_lon.get(get_ident)), {
icon: L.mapbox.marker.icon({'marker-symbol':'airport', 'marker-color': '4587f4'})
});
map.addLayer(marker);
}
for (var i = 0; i < pairs.length; i++) {
if (ident_lat.has(get_ident)){
// airport is selected
origin_lat = pairs[i][0][0].toString()
origin_lon = pairs[i][0][1].toString()
dest_lat = pairs[i][1][0].toString()
dest_lon = pairs[i][1][1].toString()
if (JSON.stringify([ident_lat.get(get_ident), ident_lon.get(get_ident)]) == JSON.stringify([origin_lat.slice(0,4), origin_lon.slice(0,4)]) || JSON.stringify([ident_lat.get(get_ident), ident_lon.get(get_ident)]) == JSON.stringify([dest_lat.slice(0,4), dest_lon.slice(0,4)])){
counter = counter + 1;
// filter it out
var generator = new arc.GreatCircle(
obj(pairs[i][0]),
obj(pairs[i][1]));
var line = generator.Arc(100, { offset: 100 });
var newLine = L.polyline(line.geometries[0].coords.map(function(c) {
return c.reverse();
}), {
color: '#fff',
weight: 1,
opacity: 0.5
})
.addTo(map);
var totalLength = newLine._path.getTotalLength();
newLine._path.classList.add('path-start');
newLine._path.style.strokeDashoffset = totalLength;
newLine._path.style.strokeDasharray = totalLength;
setTimeout((function(path) {
return function() {
path.style.strokeDashoffset = 2; // no animation == 0
};
})(newLine._path), i * 2); // no animation == 0
}
console.log("counter: ", counter);
}
else if (get_ident == undefined) {
console.log("else block");
// Transform each pair into a circle using the Arc.js plugin
var generator = new arc.GreatCircle(
obj(pairs[i][0]),
obj(pairs[i][1]));
var line = generator.Arc(100, { offset: 100 });
// Leaflet expects [lat,lng] arrays, but a lot of
// software does the opposite, including arc.js, so flip here.
var newLine = L.polyline(line.geometries[0].coords.map(function(c) {
return c.reverse();
}), {
color: '#fff',
weight: 1,
opacity: 0.5
})
.addTo(map);
var totalLength = newLine._path.getTotalLength();
newLine._path.classList.add('path-start');
// This pair of CSS properties hides the line initially
// See http://css-tricks.com/svg-line-animation-works/ for details on this trick.
newLine._path.style.strokeDashoffset = totalLength;
newLine._path.style.strokeDasharray = totalLength;
// Offset the timeout here: setTimeout makes a function run after a certain number of milliseconds
setTimeout((function(path) {
return function() {
// setting the strokeDashoffset to 0 triggers animation
path.style.strokeDashoffset = 2;
};
})(newLine._path), i * 2);
}
}
});
return (
<div className="mapbox_container">
<div id = "map" className="dark"></div>
</div>
)
}
export default Mapbox;
I'm not familiar with leaflet but, with mapbox-gl, you can set your map as following
import React from "react";
import "./styles.css";
import * as mapboxgl from "mapbox-gl";
mapboxgl.accessToken = "your-token-here";
export default function App() {
React.useEffect(() => {
const map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/light-v9",
zoom: 12,
center: [-122.447303, 37.753574]
});
}, []);
return (
<>
<div id="map" style={{ height: "100vh" }}></div>
</>
);
}
or you can also use react-map-gl like this
import * as React from "react";
import ReactMapGL from "react-map-gl";
export default () => {
const [viewport, setViewport] = React.useState({
width: "100%",
height: "100%",
longitude: 139.63270819862225,
latitude: 35.458058995332536,
zoom: 13.5,
mapStyle: "mapbox://styles/mapbox/streets-v11",
mapboxApiAccessToken:
"your-token-here"
});
return (
<div style={{ height: "100vh" }}>
<ReactMapGL {...viewport} onViewportChange={setViewport} />
</div>
);
};
You can convert the provided example into a React component by:
including mapbox css & js via cdns on index.html
<link
href="https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css"
rel="stylesheet"
/>
arc.js to make paths curved via cdn on index.html
<script src="https://api.mapbox.com/mapbox.js/plugins/arc.js/v0.1.0/arc.js"></script>
normally you could import directly flights variable via this script <script src='/mapbox.js/assets/data/flights.js'></script>
but it does not seem to work so place the json inside a constant (you can try again if it works for you using the above script)
Now you have all the libraries you need create a custom Mapbox comp as you did in your example by placing the demo code inside a useEffect :
import React, { useEffect } from "react";
import pairs from "./flights.json";
L.mapbox.accessToken =
"pk.eyJ1Ijoic2FueWFzaW4iLCJhIjoiY2tnbzA2aW9mMGI4cTJybnFvOTVzYm84aCJ9.voOP8PnCpZrEsilFflPswg";
export default function Mapbox() {
useEffect(() => {
// console.log(L.mapbox);
const map = L.mapbox
.map("map")
.setView([20, 0], 2)
.addLayer(L.mapbox.styleLayer("mapbox://styles/mapbox/satellite-v9"));
L.control
.attribution({
prefix:
'Flight data from Open Flights, under the ODbL license'
})
.addTo(map);
// Disable drag and zoom handlers.
// Making this effect work with zooming and panning
// would require a different technique with different
// tradeoffs.
map.dragging.disable();
map.touchZoom.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
if (map.tap) map.tap.disable();
// Transform the short [lat,lng] format in our
// data into the {x, y} expected by arc.js.
function obj(ll) {
return { y: ll[0], x: ll[1] };
}
for (var i = 0; i < pairs.length; i++) {
// Transform each pair of coordinates into a pretty
// great circle using the Arc.js plugin, as included above.
var generator = new arc.GreatCircle(obj(pairs[i][0]), obj(pairs[i][1]));
var line = generator.Arc(100, { offset: 10 });
// Leaflet expects [lat,lng] arrays, but a lot of
// software does the opposite, including arc.js, so
// we flip here.
var newLine = L.polyline(
line.geometries[0].coords.map(function (c) {
return c.reverse();
}),
{
color: "#fff",
weight: 1,
opacity: 0.5
}
).addTo(map);
var totalLength = newLine._path.getTotalLength();
newLine._path.classList.add("path-start");
// This pair of CSS properties hides the line initially
// See http://css-tricks.com/svg-line-animation-works/
// for details on this trick.
newLine._path.style.strokeDashoffset = totalLength;
newLine._path.style.strokeDasharray = totalLength;
// Offset the timeout here: setTimeout makes a function
// run after a certain number of milliseconds - in this
// case we want each flight path to be staggered a bit.
setTimeout(
(function (path) {
return function () {
// setting the strokeDashoffset to 0 triggers
// the animation.
path.style.strokeDashoffset = 0;
};
})(newLine._path),
i * 100
);
}
}, []);
return <div id="map" className="light"></div>;
}
Demo

How to toggle a rectangle grid using react-leaflet's LayerControl?

I want to show or hide a grid of rectangles (the overlay) over a map (the base layer).
I'm using the react Leaflet layers control : doc
Problem : My grid shows all the time even if I uncheck the check box
My grid :
class Grid extends MapControl {
createLeafletElement(props) {
const {
leaflet: { map },
} = props;
const minLng = -4.89;
const minLat = 41.29;
const maxLng = 9.65;
const maxLat = 51.22
const nbColumn = 10;
const nbRow = 10;
const rectWidth = maxLng - minLng;
const rectHeight = maxLat - minLat;
const incrLat = rectHeight / nbColumn;
const incrLng = rectWidth / nbRow;
let column = 0;
let lngTemp = minLng;
let latTemp = minLat;
let rect;
const arrRect = [];
while (column < nbColumn) {
let row = 0;
latTemp = minLat;
while (row < nbRow) {
const cellBounds = [[latTemp, lngTemp], [latTemp + incrLat, lngTemp + incrLng]];
rect = L.rectangle(cellBounds, {color: "#1EA0AA", weight: 1}).addTo(map);
arrRect.push(rect);
latTemp += incrLat;
row += 1;
}
lngTemp += incrLng;
column += 1;
}
return rect;
}
}
In my leaflet component :
class Leaflet extends Component {
...
render() {
return (
<Map
<LayersControl>
<LayersControl.BaseLayer name="Open Street Map" checked="true">
<TileLayer attribution='© OpenStreetMap
contributors'
url={this.state.url}
/>
</LayersControl.BaseLayer>
<LayersControl.Overlay name="Grid1">
<LayerGroup>
<Grid />
</LayerGroup>
</LayersControl.Overlay>
</LayersControl>
I did not manage to load your grid so I provide another simpler grid example.
To control the Grid's visibility you need to use react-leaflet's updateLeafletElement method to trigger prop changes on your custom react-leaflet component. Pass a showGrid prop to be able to control Grid's visibility.
updateLeafletElement(fromProps, toProps) {
const { map } = this.props.leaflet;
if (toProps.showGrid !== fromProps.showGrid) {
toProps.showGrid
? this.leafletElement.addTo(map)
: this.leafletElement.removeFrom(map);
}
}
then in your map component listen to leaflet's overlayadd & overlayremove to be able to toggle a local flag which will control the visibility of the grid using an effect:
useEffect(() => {
const map = mapRef.current.leafletElement;
map.on("overlayadd", (e) => {
if (e.name === "Grid1") setShowGrid(true);
});
map.on("overlayremove", (e) => {
if (e.name === "Grid1") setShowGrid(false);
});
}, []);
<LayersControl.Overlay
checked={showGrid}
name="Grid1"
>
<LayerGroup>
<Grid showGrid={showGrid} />
</LayerGroup>
</LayersControl.Overlay>
Edit:
The App component as class based component it will look like this:
export default class AppWithNoHooks extends Component {
state = {
showGrid: false
};
mapRef = createRef();
componentDidMount() {
const map = this.mapRef.current.leafletElement;
map.on("overlayadd", (e) => {
if (e.name === "Grid1") this.setState({ showGrid: true });
});
map.on("overlayremove", (e) => {
if (e.name === "Grid1") this.setState({ showGrid: false });
});
}
...
I don't get the error you mentioned.
Demo

Categories

Resources