This is the first day of my participation in the August Text Challenge.More challenges in August
Context API
The context API provides a mechanism for components to “talk” to each other without passing data and functions as props or dispatching a large number of events. This is an advanced feature, but a useful one.
Take an example application that uses Mapbox GL maps. We want to display tags using the
The context API has two parts: setContext and getContext. If the component calls setContext(key,context), then any child component can retrieve the context using const Context =getContext(key).
Let’s set up the context first. In map. svelte, import setContext from svelte, import key from mapbox.js, and call setContext:
import { onMount, setContext } from 'svelte';
import { mapbox, key } from './mapbox.js';
setContext(key, {
getMap: () = > map
});
Copy the code
The context object can be anything you like. As with lifecycle functions, setContext and getContext must be called during component initialization. Calling it later (for example, inside onMount) throws an error. In this case, because the mapping is not created until the component is mounted, our context object contains a getMap function rather than the mapping itself.
In mapMarket.svelte, we can now get a reference to a Mapbox instance:
import { getContext } from 'svelte';
import { mapbox, key } from './mapbox.js';
const { getMap } = getContext(key);
const map = getMap();
Copy the code
Labels can now be added to maps.
A more complete version of
can also handle deletions and prop changes, but we will only demonstrate context here.
Context keyword
In mapbox.js, you will see the following lines:
const key = {};
Copy the code
We can use any name for the key: for example, we can use setContext(‘mapbox’,…) . The disadvantage of using strings is that different component libraries may accidentally use the same; Using objects means that the keys are guaranteed not to collide in any case (because objects themselves only have reference equalities, i.e. {}! =={} while “x”===”x”), even if there are multiple different context operations on multiple component layers.
Context and Storage
Context and storage seem similar. The difference is that storage can be used by any part of the application, whereas context is only available to components and their children. This is useful if you want to work with multiple instances of a component, and the state of one instance does not interfere with the state of the others.
In fact, you can use both together. Since the context is not passive, time-varying values should be stored:
const{ these, are, stores } = getContext(...) ;Copy the code
Complete code:
Mapbox. Js:
import mapbox from 'mapbox-gl';
// https://docs.mapbox.com/help/glossary/access-token/
mapbox.accessToken = MAPBOX_ACCESS_TOKEN;
const key = {};
export { mapbox, key };
Copy the code
MapMarker. Svelte:
<script>
import { getContext } from 'svelte';
import { mapbox, key } from './mapbox.js';
const { getMap } = getContext(key);
const map = getMap();
export let lat;
export let lon;
export let label;
const popup = new mapbox.Popup({ offset: 25 })
.setText(label);
const marker = new mapbox.Marker()
.setLngLat([lon, lat])
.setPopup(popup)
.addTo(map);
</script>
Copy the code
Map. Svelte:
<script>
import { onMount, setContext } from 'svelte';
import { mapbox, key } from './mapbox.js';
setContext(key, {
getMap: () = > map
});
export let lat;
export let lon;
export let zoom;
let container;
let map;
onMount(() = > {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/mapbox-gl/dist/mapbox-gl.css';
link.onload = () = > {
map = new mapbox.Map({
container,
style: 'mapbox://styles/mapbox/streets-v9'.center: [lon, lat],
zoom
});
};
document.head.appendChild(link);
return () = > {
map.remove();
link.parentNode.removeChild(link);
};
});
</script>
<div bind:this={container}>
{#if map}
<slot></slot>
{/if}
</div>
<style>
div {
width: 100%;
height: 100%;
}
</style>
Copy the code
App. Sevlte:
<script>
import Map from './Map.svelte';
import MapMarker from './MapMarker.svelte';
</script>
<Map lat={35} lon={84} zoom=3.5} {>
<MapMarker lat=37.8225} { lon={122.0024} label="Svelte Body Shaping"/>
<MapMarker lat=33.8981} { lon={118.4169} label="Svelte Barbershop & Essentials"/>
<MapMarker lat=29.7230} { lon={95.4189} label="Svelte Waxing Studio"/>
<MapMarker lat=28.3378} { lon={81.3966} label="Svelte 30 Nutritional Consultants"/>
<MapMarker lat=40.6483} { lon={74.0237} label="Svelte Brands LLC"/>
<MapMarker lat=40.6986} { lon={74.4100} label="Svelte Medical Systems"/>
</Map>
Copy the code
This section has many concepts and rich examples. It is recommended to visit the official website for an example: context-API