02. React + Leaflet. Component State. Basemap, TileLayer
Наш сайт – Source code (follow us) – Telegram – follow us in telegram @geofuckCode …
In this video we keep working
with library React and development of
using it and
In our last session we went through
app creation, adding tile layer,
i.e. basemap, and
adding marker with pop-up window.
Our map look so,
and after click on marker window appeared.
Today we move on and explore
the change of state of react component,
i.e. state up.
We'll do that on the example of
basemap change in app.
Now our app
is as follows:
there're map, marker, and on the right-hand side
vidget of basemap change is shown.
We can choose the name
of basemap, and tile layer, the layer of basemap,
will be changed to the respective one.
Let's switch to our code and
consider in more detail, what
was done. Now we're looking at code,
let's remember how the app is built.
There's file index.html
with div and its id="root", than to id="root"
to index.js the component App
is added. It's imported from the file App.
Accordingly, in the file App
component MapComponent that was imported
from the file MapBasemap is returned.
And here, in MapComponent, we are going to
work today. So inside of MapComponent there's
object state with its keys-values,
and one of them is basemap
with string value osm.
We'll return to function onBMChange
a bit later. There's also function render,
that consists of the following things: firstly,
the value center and object basemapsDict
are created. The object basemapsDict
contains three keys – osm, hot and dark.
They are themes that basemap can have,
and their values are
links to tile service of basemaps
that we'll use.
These services are free-of-charge, and
and they were taken fro this app. Here
you can see the list of basemaps
you can use and
easily connect to Leaflet-map.
Accordingly, we took three examples from there,
so we've kind of
small dictionary: on the left-hand side
any key marking of the map,
tile layer, and on the right-hand side
the link to tile service. And then
within the component
the map with tile background is returned.
Value in the feature url,
value from basemapsDict are used.
Key is chosen from the state
of that component, i.e. this.state.basemap
is used. In this case basemap
equals to osm, and here
the value osm will be substituted,
so it will be basemapsDict['osm'].
These tile layer and tile service
will be utilized.
How should the tile base layer
In what way will
this.state.basemap vary in order to
substitute osm or hot or dark here?
We created our own component
and called it Basemap.
It has two propeties. First is
basemap that equals to this.state.basemap,
second is onChange,
that equals to method this.onBMChange.
These two properties will be transferred
inside the created component Basemap.
They can be referred
through this.props. In fact,
they will be properties of Basemap.
You can refer them
Let's open component Basemap.
Here we see the class Basemap
that is exported by default.
Inside of this class, there are method onChange
and render. Let's start from render.
What do we receive in fact, which JSX?
We obtain div with
i.e. select with three options,
probable variants of choice.
We clarify in HTML Help,
what the tag select is, which attributues
it has. First attribute is value,
this.props.basemap, i.e. what we exported
from file MapBasemap.js here (this basemap
will be recoded),
will be transferred into it.
Right now value
equals to osm.
There's also attribute onChange, i.e.
which algorithm will occur
when value in this select
Scenario this.onChange will happen, i.e.
this method will be turned on,
and anything will occur within its framework.
Let's look at app, how
this certain div seems.
This is our select
and three options – OSM,
OSM HOT and DARK. So we just saw
html and respective styles because
basemaps-container. In the file Map.css
certain styles for this class are set.
Such as position, top, right, i.e.
where it will be located – at the top
and on the right, on the distance of
20 pixels from screen border; z-index
necessarily, and for
tag select inside of the element
with this class we set
width and heigth –
200 и 20 pixels respectively.
So we placed this element,
it has three pillars; now we look
what happens when we choose
concrete one of these three values.
Method onChange is realized, i.e.
code is inside of this method. Let's
return this e.currentTarget.value
as a console.log.
Then let's open the app,
open the code, move to console and change
the name of base layer we chose.
The value, relevant to our choice,
for DARK ir returns dark,
for OSM HOT – hot,
for OSM – osm.
So all these three values
which are transferred to method onChange
when they are chosen. We may note that
thse values are equal to
keys in object basemapsDict,
i.e. osm, hot и dark
to choose respective tile service
for basemap. Now
we enter this value (osm, hot or
dark) – to the variable bm
(abbreviation for basemap). Algorithm is as follows:
if this.props.onChange exists, i.e.
this method is transferred,
as we can see,it transferred in request
this.props.onChange with argument bm.
So it's requested, as we
called the property basemap which
was transferred right here, – this.props.basemap,
so this.props.onChange calls
function this.onBMChange, i.e.
our code will be here. So in this instance
function with argument bm.
In both places
the state in component MapComponent will be changed,
i.e. this.setState is method
which is responsible for the state change.
On the input this method receives object
with the key as property
that is in the property
state and value with what we want to
rewrite this state.
So we receive osm, hot or dark,
one of three lines,
and we rewrite state basemap
to this line. As soos as
we replace it, everything it this app
that depends on
оn this.state.basemap, will be rerendered.
Popup, TileLayer, our url
basemap has a bit new look;
our chosen option in component basemap
is altered, i.e.
value is modified. Again,
which algorithm do we apply?
We entered attribute onChange into tag select.
Accordingly, in response to changes
of value the function onChange is triggered.
Function received value
And this value is transferred
to another file, file MapBasemap.js,
to class MapComponent, i.e. to component,
to function onBMChange, because this.props.onChange.
We look what is this.props,
and this.props is basemap and onChange.
Consequently, there're two properties here – basemap and onChange.
this.props.onChange, as we may see, is this.onBMChange,
meaning this method.
the state of MapComponent is modified,
i.e. basemap changed to the line
that came from values of
option, i.e. either osm
or hot or dark. For example, basemap
altered to hot –
in that event the url of TileLayer
was modified immediately,
so here hot was substituted.
this link will be taken,
and tile service will use
this link for building
The word hot is also
utilized, and in Popup
the phrase "Выбрана тема" is shown and
the word hot is substituted. So
theme is chosen,
pretty much what will be written –
"theme hot is chosen". Or
it will be written in this way using kind of JSX –
it will be written so, that is the same.
Now we're clear on
how the state works,
how it can be modified using
setState changes the state. What does it take
to the input? Object within which
the key responsible for the state
that will be modified and for
the new value of this state
should be. We also went through
the creation of
our own component.
We also learned that during previous session,
but in this video
we created component Basemap and utilized it
with two properties – basemap и onChange.
In fact, we requested this component.
We've already called for this components
via this.props. So in the app when changing
options link to tile service and basemap
Let's refer to one
essential detail: what does "this"
in method onBMChange equal to?
It means we uncomment line console.log(this) and
save. We delete
console.log from here to prevent
any reduntat output to console and look
what is "this" in selection of basemap.
As we see, it's our MapComponent:
it has our state
that we created within before
as we have method
Now we modify syntax
in setting up method onBMChange and save the app
Then we modify again.
Now the error pops up
and, as we can see, "this" was changed.
"this.setState is not a function" occurs,
i.e. there's no method set.State
for "this". "This" changed,
context altered, and now
it's basemap and onChange, meaning these are
features we transferred
to component Basemap. I.e. in fact "this"
is different, and we can't request
our setState in method onBMChange. Thus,
onBMChange is requested, perfect, console.log(this)
is also called, but "this" is another.
"This" is not MapComponent, and it can't
have method setState. Consequently,
in this instance we may apply two methods –
either to replace syntax by this one, so
"this" will be redefined, or
the entry will be equivalent to
this construction. So if we
switch syntax back, i.e.
use the those syntax
that didn't work,
without this construction, and launch
the app, while saving current file,
everything will run again.
In fact, what do we do inside of this construction?
and redefine context of the function
that we apply. You can read about method bind
and change of context in Help.
Why didn't we use
This one is shorter, easier.
In turn, it's experimental,
this syntax is experimental,
so in this video
of transfer required "this"
into method onBMChange.
Let's comment out this line.
The final thing we learn today is
how we can add new theme into our small app,
how can make four, not three options of
Accordingly, we go into familiar web-site,
the to console of developer,
Network and choose any map
we want to display.
For example, CyclOSM.
We choose it,
move it a tiny bit, then requests to
tile service are formed. We see a lot of
requests, click on any of them and then see
link https and so on and so on. Then we copy
the link, call this map "cycle".
Now we need to add
new key "cycle"
with value and replace
concrete requests in the right places
by our coordinates of tiles, i.e. x, y, z, s.
Yes, we changed. And now we must add
the value of option
as a cycle.
Let's call it however we want,
for example, CYCLE MAP. We can call it
by any name here. Then save and move to
the app. Now whilee choosing CYCLE MAP
our map is replaced by
CyclOSM. If we turn, maybe,
to Switzerland –
we see again
our CYCLE MAP.
We just need to look
where the request gos, obtain this link
and past it to our app,
so it's not that complicated. Accordingly,
on our marker we see
"Theme "cycle" is chosen".
That's it. in this video we've figured out,
how to use method setState, i.e.
how to change state within the component,
and conqequently we understood that
all element dependent on this state
will be automatically rerendered
while changing the state.
We've built our own
We've learned how to request this.props,
how to transfer methods from other components,
i.e. we created method in one component,
called it in other component
using this.props, and context
remains the same as context of
parental component. In this case
we applied experimental
syntax, you may utilize
constructor, method bind for transfer
of certain context to concrete
function. That's all for today.
If anything is still unclear, if you have
any proposals, you can write them
in comments. Next session will be dedicated
to the same topic –
If you have any suggestions
what to watch, your comments are also welcome.
We read all of them.