3

I'm learning to use both react and mapbox,but am struggling with why my mapbox map is not rendering properly when loaded through React. When I load it normally (without React.js), there is no problem, as this following code works and the map appears normally:

<script src="https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.js"></script>
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.css"/>

<div> id="map"></div>

    <script>                
    var map = L.mapbox.map('map', 'blabla.blabla').setView([lat, long], 9);
    </script>

But when I do it the following way, the map often doesn't appear at all, or when it does, I see just a portion of it in the top left of the div.

<script src="path/to/react.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.js"></script>
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.css"/>

<div id="react-content">
    <script src="path/to/react/content.js'></script>
</div>

//now inside react/content.js, there is a mapbox component inside an outer component. I'm leaving out the rest of the code to save space, and I believe that I am rendering the OuterComponent and the MapBoxMap component correctly inside that.

var MapBoxMap = React.createClass({
    componentDidMount: function() {
        L.mapbox.accessToken = this.props.accessToken;
        var map = L.mapbox.map(this.getDOMNode(), this.props.mapId)
            .setView([15, -105], 9);            
    },
    render: function() {
        return (
                <div id="map"></div>
        );
    }
});

Doing things like zooming, or opening the chrome developer tools seems to make the map appear sometimes. I don't know what is going on. Is the component not mounted properly when I attempt to render the map? I thought that is what componentDidMount was supposed to take care of? I would really appreciate any insight! Alos, this map is being rendered inside some Zurb Foundation elements, so I don't know if that makes a difference?

2
  • 1
    Those 'zurb foundation elements' probably have a zero-height until after our MapBoxMap is rendered. When you open the developer tools, you're resizing your window, which triggers the map to re-render properly. You're using your componentDidMount() properly, but you may want to either set the #react-content height explicitly, or refresh your map once the other components load. Commented Mar 8, 2015 at 21:14
  • 1
    side note: JSX is XML, not HTML, so you don't need a separate end tag. <div id="map" /> will suffice. Commented Mar 8, 2015 at 21:15

1 Answer 1

7

You're missing the related CSS? You always need to set the height of the element:

html, body, #map {
    height: 100%;
}

I am unable to test because of React but it sounds like the map is unable to get the correct dimensions from the element. That usually happens if you don't set the correct CSS or the element has display: none; If setting the correct CSS doesn't work for you can try invalidating the size so the map will reset itself. L.mapbox.Map has a invalidateSize method you can call, see:

http://leafletjs.com/reference.html#map-invalidatesize

Sign up to request clarification or add additional context in comments.

3 Comments

I have quite a bit of experience with React, and the CSS height is almost certainly the issue. I see this all the time with google maps code, since it inherits the renderable map area from the height of its component. My hunch is that the height is at 0 for the #react-content for some other reason, and gets set >0 by something that renders after the initial rendering of the map. Opening the console makes the map appear because it's forcing the window to resize, which triggers the map to render again.
@JoshfromQaribou Thank you for helping Josh. Your answer led me to find that since the map was embedded in an accordion div which initially was not displayed, it was necessary to call invalidateSize() after its accordion item was displayed. Thank you for taking the time to help :) I really appreciate it :))
@iH8 Thank you for taking the time to help. You led me to the answer, and I really appreciate it. I suppose that the Foundation accordion initially renders the items not displayed as "display: none" which you said in your post. Now, once I click the tab to display the accordion item with the map in it, I have a callback to reload the map, and it works! I really appreciate your help :))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.