简体   繁体   中英

react/react-leaflet not immediately loading information

Example of issue

import firebase from 'firebase/app';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import { OpenStreetMapProvider } from 'leaflet-geosearch'
import SearchControl from "./SearchControl";

const userId = sessionStorage.getItem('uid')
const fullNames = []
const provider = new OpenStreetMapProvider()
var vendors = []

const VendorMap = (props) => {
    firebase.firestore().collection("vendors")
        .where('belongsTo', '==', userId)
        .get()
        .then(querySnapshot => {
            querySnapshot.forEach((doc) => {
                if(fullNames.includes(doc.data().fullName) == false) {
                    fullNames.push(doc.data().fullName)
                    provider.search({query: doc.data().address}).then(function (result) {
                        vendors.push([doc.data(), [result[0].y, result[0].x]])
                    }).catch((error) => {
                        console.log("Error getting collection: ", error)
                    })
                }
            })
        }).catch((error) => {
            console.log("Error getting collection: ", error)
        })

    return (
        <MapContainer center={[51.505, -0.09]} zoom={3} scrollWheelZoom={true}>
            <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
            <SearchControl provider={provider} showMarker={true} showPopup={true} popupFormat={({ query, result }) => result.label} maxMarkers={3} retainZoomLevel={false} animateZoom={true} autoClose={false} searchLabel={"Address to search for..."} keepResult={true} />
            {vendors.map((vendor) => 
                <Marker key={vendor[0].fullName} position={[vendor[1][0], vendor[1][1]]}>
                    <Popup>
                        <span>{vendor[0].fullName}</span>
                    </Popup>
                </Marker>
            )}
        </MapContainer>
    )
}

export default VendorMap

The above link is a video of my issue (its only 10 seconds). React is not immediately loading all of the map markers every time it loads. Sometimes all of the markers load, sometimes only 1 does and I have to click on the navigation bar link for the rest to load.

I am not understanding what the issue could be since I am adding all of the markers one after another to the map. React also doesn't seem to be loading the information from firestore correctly as when I log into the website, I have to completely refresh the website before information begins to load.

If anyone has any insight into what I may be doing wrong and how to fix this, it would be great. I am really new to NodeJS and ReactJS so excuse any common issues on my end.

I am not able to reproduce your issue but the first two things you need to change is:

  1. Place the async operation inside a useEffect hook to load only once when the page loads.
  2. use a useState hook to store the data received from the async operation inside VendorMap component because storing the data in a variable outside the functional component like you do might have unexpected results as React does not know when to update the DOM and compare the old with the new values.

As a result create a local variable using a useState hook

const [vendors, setVendors] = useState([]);

useEffect(() => {
   firebase.firestore().collection("vendors")
        .where('belongsTo', '==', userId)
        .get()
        .then(querySnapshot => {
            querySnapshot.forEach((doc) => {
                if(fullNames.includes(doc.data().fullName) == false) {
                    fullNames.push(doc.data().fullName)
                    provider.search({query: doc.data().address}).then(function (result) {               
                       setVendords(yourVariable) // update the vendors array
                    }).catch((error) => {
                        console.log("Error getting collection: ", error)
                    })
                }
            })
        }).catch((error) => {
            console.log("Error getting collection: ", error)
        })
}, []);

Inside setVendors update vendors variable. I am not sure regarding the data you receive that is the reason I did not put the exact value

  1. If you update fullNames like vendors follow the same pattern as for vendors variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM