|
1 | 1 | import * as React from 'react'; |
2 | | -import {useContext, useEffect, useMemo, useState, useRef, cloneElement} from 'react'; |
| 2 | +import {useContext, useEffect, useMemo, useCallback, useState, useRef, cloneElement} from 'react'; |
3 | 3 | import {MapContext} from './map'; |
4 | 4 | import assert from '../utils/assert'; |
5 | 5 | import {deepEqual} from '../utils/deep-equal'; |
@@ -83,17 +83,16 @@ export function Source(props: SourceProps) { |
83 | 83 | const [, setStyleLoaded] = useState(0); |
84 | 84 |
|
85 | 85 | const id = useMemo(() => props.id || `jsx-source-${sourceCounter++}`, []); |
| 86 | + const forceUpdate = useCallback(() => setStyleLoaded(version => version + 1), []); |
86 | 87 |
|
87 | 88 | useEffect(() => { |
88 | 89 | if (map) { |
89 | | - /* global setTimeout */ |
90 | | - const forceUpdate = () => setTimeout(() => setStyleLoaded(version => version + 1), 0); |
91 | | - map.on('load', forceUpdate); |
| 90 | + // Fired on initial load signaling the map is ready to add custom sources |
| 91 | + // Subsequently fired on style changes |
92 | 92 | map.on('styledata', forceUpdate); |
93 | 93 | forceUpdate(); |
94 | 94 |
|
95 | 95 | return () => { |
96 | | - map.off('load', forceUpdate); |
97 | 96 | map.off('styledata', forceUpdate); |
98 | 97 | // @ts-ignore |
99 | 98 | if (map.style && map.style._loaded && map.getSource(id)) { |
@@ -125,6 +124,20 @@ export function Source(props: SourceProps) { |
125 | 124 | } |
126 | 125 | propsRef.current = props; |
127 | 126 |
|
| 127 | + useEffect(() => { |
| 128 | + if (!source) { |
| 129 | + // on `styledata` event, `map.isStyleLoaded()` still returns false. |
| 130 | + // `load` and `style.load` only fire once and not when `isStyleLoaded` changes from true to false to true. |
| 131 | + // `sourcedata` potentially suggests that `isStyleLoaded` has changed. But it fires on every tile load. |
| 132 | + // Unsubscribe once source is added. |
| 133 | + map.on('sourcedata', forceUpdate); |
| 134 | + return () => { |
| 135 | + map.off('sourcedata', forceUpdate); |
| 136 | + }; |
| 137 | + } |
| 138 | + return undefined; |
| 139 | + }, [map, source]); |
| 140 | + |
128 | 141 | return ( |
129 | 142 | (source && |
130 | 143 | React.Children.map( |
|
0 commit comments