Search code examples
reactjsopenlayers

write controls in openlayer in jsx format


I'm using OpenLayers in my react project and for map controls I make a new component to use it. default controls like full-screen control are implemented by me like this:

import { useContext, useEffect } from 'react';
import { FullScreen } from 'ol/control';
import MapContext from '../MapProvider';

function FullScreenControl() {
  // /////////////////////////////////////////
  // Contexts
  // /////////////////////////////////////////
  const map = useContext(MapContext);

  // /////////////////////////////////////////
  // Effects
  // //////////////////////////////////////////

  useEffect(() => {
    if (!map) return;
    const fullScreenControl = new FullScreen({ tipLabel: 'تمام صفحه' });
    map.addControl(fullScreenControl);

    return () => {
      map.removeControl(fullScreenControl);
    };
  }, [map]);

  return null;
}
export default FullScreenControl;

I want to create custom controls in my code for example map legend control. after some searching I find that I should use new Controll from

import { Control } from 'ol/control';

but the problem is the element in the control constructor only accepts HTML but I want to pass jsx to it.

 new Control({
      element:<h1>hi</h1>
    })

Solution

    • Easy: I suggest you try rlayers - https://github.com/mmomtchev/rlayers which supports this feature and hides all the complexity of doing maps in React (I am the author)

    • Harder: I am not sure you understand what the element argument is - it is not HTML code to be rendered - but rather an existing DOM element. If you want to do this in React, you have to use references - create the DOM element by rendering a component and assign it a reference:

    const ref = React.createRef(null);
    functionn SomeElement() {
      return <h1 ref={ref}>hi</h1>;
    }
    

    then pass it your control:

    new Control({element: ref.current})
    

    However this behavior is generally considered to be against React guidelines. SomeElement will be a dangerous component that won't be reusable. Maps in React are difficult.