Reputation: 424
I have a react functional component that takes a button as a variable, and launches a function on click. The button is a variable because this function is getting imported into another functional component, and the button is created in this external function. I would also like to set and toggle the button class on click, to indicate whether the button/tool is active or not. I have not been able to find a way to toggle the className. In my example I am using the useState hook to set a default value for the class, and then in the click function I am changing the value of the class depending on the value of another useState hook. This does not show any class for the button. I can specify the className as activeClass outside of the click function and it will that class, but can't figure out how to toggle. I have also tried setting the className in the return statement like this: <button className={btnActive ? 'one_class' : 'two_class'} onClick={function}</>
but this also does not set the class. What am I doing wrong? This is my first attempt at using the react framework.
import React from 'react';
import { useInput } from '../hooks/useInput';
import {
placesSource,
places_lyr,
}
from "../qgis2web/layers";
import {
increaseThrobberCounter,
decreaseThrobberCounter
}
from "../qgis2web/throbberCounter";
import { addLayer, getErrorMessage, removeLayer } from "../qgis2web/qgis2web";
import { add_geojson_feats } from "../qgis2web/addGeojsonFeatures";
declare const ol, $, toastr;
const GetPlacesControl = ({ map, launchButton }) => {
const [btnActive, setBtnState] = React.useState<boolean>(false);
const [activeClass, setClass] = React.useState("fas fa-globe-americas");
function clear_places_features(map) {
placesSource.clear();
removeLayer(places_lyr);
}
const toggle_get_places = (launchButton) => {
setBtnState((btnActive) => {
setClass((activeClass) => {
if (btnActive) {
setClass("fas fa-ban");
$('html,body').css('cursor', 'default');
map.un('click', runCallback);
clear_places_features(map);
} else {
setClass("fas fa-globe-americas");
$('html,body').css('cursor', 'crosshair');
map.on('click', runCallback);
}
launchButton.className = activeClass;
return launchButton.className;
});
return !btnActive;
});
}
const runCallback = React.useCallback((evt) => {
clear_places_features(map);
$.ajax({
type: "POST",
contentType: "application/json;charset=utf-8",
url: "api/get_places?x=" + evt.coordinate[0] + "&y=" + evt.coordinate[1],
traditional: "true",
datatype: "json",
mimeType: 'application/json',
}).done(function (response) {
const places_feats = new ol.format.GeoJSON().readFeatures(response);
if (places_feats.length == 0) {
toastr.warning('no records found, try again');
} else {
placesSource.addFeatures(places_feats);
map.getView().fit(placesSource.getExtent());
places_lyr.setVisible(true);
addLayer(places_lyr);
}
}).fail(function (jqXHR) {
let msg = getErrorMessage(jqXHR);
toastr.error(msg);
}).always(function () {
decreaseThrobberCounter();
});
}, []);
React.useEffect(() => {
const get_coords_on_click = (evt) => {
let loc_coords = evt.coordinate;
return loc_coords;
};
launchButton.addEventListener('click', toggle_get_places, false);
map.on('singleclick', get_coords_on_click);
return () => {
launchButton.removeEventListener('click', toggle_get_places);
map.un('singleclick', get_coords_on_click);
};
}, []);
return (
<button onClick={launchButton.toggle_get_places}></button>
);
};
export default GetPlacesControl;
Upvotes: 1
Views: 282
Reputation: 1280
Your code does not work
You should try to use useRef
and classList.add/remove
Upvotes: 2