Trying to work with openlayers,reactjs and golden-layout. Golden-layout configuration is one row with two "react-components" inside it. Openlayers does render map in one "react-component" of golden-layout but not in other "react-component".

Here is code i am trying.

    import Map from 'ol/Map';

    import View from 'ol/View';
    import TileLayer from 'ol/layer/Tile';
    import XYZ from 'ol/source/XYZ';
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    // import TestComponent from './App';
    import GoldenLayout from "golden-layout";
    import * as serviceWorker from './serviceWorker';
    import "golden-layout/src/css/goldenlayout-base.css";
    import "golden-layout/src/css/goldenlayout-dark-theme.css";
    import "ol/ol.css";
    window.React = React;
    window.ReactDOM = ReactDOM;

    var map = new Map({
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
          })
        })
      ],
      view: new View({
        center: [0, 0],
        zoom: 2
      })
    });


    class TestComponent extends React.Component{
      componentDidMount() {
        map.setTarget("map")
      }
        render() {
            return (<div id="map"></div>)
        }
    }

    var myLayout = new GoldenLayout({
        content: [
          {
            type: 'row',
            content:[
              {
                type:'react-component',
                component: 'test-component',
              },
              {
                type:'react-component',
                component: 'test-component',
              }
            ]
          }
        ]
    });


    myLayout.registerComponent( 'test-component', TestComponent);

    myLayout.init();

Here is result. openlayers with reactjs and golden-layout

2

There are 2 best solutions below

0
On BEST ANSWER

Need two instances of openlayers map and also element with unique id.

if only one instance of map used, then changing it's target element will not render map in both elements.

So need two instances of map, with unique element id.

Also golden-layout renders the provided react component in it's layout/reat-component which means you need to set the id in componentDidMount() function of reactjs component life cycle. componentDidMount

Here is code that work.

    import Map1 from 'ol/Map';
    import Map2 from 'ol/Map';
    import View from 'ol/View';
    import TileLayer from 'ol/layer/Tile';
    import XYZ from 'ol/source/XYZ';
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    // import TestComponent from './App';
    import GoldenLayout from "golden-layout";
    import * as serviceWorker from './serviceWorker';
    import "golden-layout/src/css/goldenlayout-base.css";
    import "golden-layout/src/css/goldenlayout-dark-theme.css";
    import "ol/ol.css";
    window.React = React;
    window.ReactDOM = ReactDOM;

    var map1 = new Map1({
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
          })
        })
      ],
      view: new View({
        center: [0, 0],
        zoom: 2
      })
    });

    var map2 = new Map2({
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
          })
        })
      ],
      view: new View({
        center: [0, 0],
        zoom: 2
      })
    });


    class TestComponent extends React.Component{
      constructor(){
        super()
        this.myref = React.createRef()
      }
      componentDidMount() {
        this.myref.current.setAttribute("id",this.props.id)
        this.props.map.setTarget(this.props.id)
      }
      render() {
          return (
            <div ref={this.myref}></div>
          )
      }
    }

    var myLayout = new GoldenLayout({
        content: [
          {
            type: 'row',
            content:[
              {
                type:'react-component',
                component: 'test-component',
                props:{id:"map1",map:map1}
              },
              {
                type:'react-component',
                component: 'test-component',
                props:{id:"map2",map:map2}
              }
            ]
          }
        ]
    });


    myLayout.registerComponent( 'test-component', TestComponent);

    myLayout.init();
2
On

You need to change the id of the second map.

First of all, the value of id attribute should be unique across the whole app (well, at least unique in the output that you are currently showing to the user). Both of your maps are pointing at the same div element with id="map" (probably the first that they find).

So your first map can potentially target div with id="map1" and the second map component should target div with id="map2".

So you should try to put the map id as a prop to both of your components and set the target id and div id in render() method based on this property

Please, let me know if my answer helped you!