React is a JavaScript library used to build HTML and it is developed by Facebook. If you need a lot of dynamism in your app then it will be the right choice. And, we will see how React is used to build HTML and how it changes the way we think about web application and user interfaces element.

At the end of this tutorial, you will be able to build an application using React which will look like this:





And the source code for this app is available in the following link:

https://bitbucket.org/Tarique81/stadium-search-in-map/src

It contains a list of football stadiums in London and their location on the map with a simple search. Hope this will be fun. Let's start….

For creating this application you need to have a basic knowledge of JavaScript and a little bit React. For creating a React app you need to have node js installed in your pc. Node is just an engine to execute JavaScript. To check type:

node -v





It will show the version of node and if not then you need to install node. To create a react app there are a lot of things that need to be configured like webpack, babel, react, eslint and few other dependencies. We will not go for much details on these things in this tutorial. Webpack is a tool for bundling our assets together. It compiles the js files and creates a single js file which should be ready for serving the browser. Eslint is a tool for writing nice JavaScript code. Babel allows us to write modern JavaScript which compiles JavaScript to the latest version(ES6). But the good news is Facebook provides us a default configuration for creating a boilerplate of a react app. So, to have this just type:

npm install -g create-react-ap

npm is a node package manager which come by default with node. If you have installed node then you will be able to use npm. Now, we are ready to go. First, go to your app directory and create an app by typing:

create-react-app app-name





This command will handle every configuration for you. After this, go to your app-name directory where you will be able to see some folders whose root directory is app-name and some other folders like the public, src etc. We will not go much detail on these. Public folder contains our asset and src folder contains our components and other js files. Be sure you are in your app-name directory and type:

npm start





Then if everything goes fine it will automatically take you to localhost:3000 and will look like:





If this screen appears then you are ready to go. React is all about creating components. For this instance, on the left side we will have a list of football stadiums and on the right side, we will have a google map. So, the stadium will be a component and map will be another component. Inside src folder create a directory named components. We will write the components needed for this project inside this folder.

So let's create the structure of our app inside the App.js file. Add the following file in your App.js file

<div className="app"> <div className="main"> <div className="search"> </div> <div className=" stadiums"> </div> </div> <div className="map"> </div> </div>





So we have search, stadiums for listing the football stadiums and lastly map for showing the location of the stadiums. Now, we will create the layout for displaying our components. I will use css flex-box for this. I will not go into much detail about this. Just add the following code to your App.css file under src directory

.app{ display: flex; } .main{ flex-basis: 60%; display: flex; flex-direction: column; } .map{ flex-grow: 1; height: 100vh; top: 0; position: sticky; } .stadium display: flex; flex-wrap: wrap; align-content: flex-start; }





At this stage our app contains nothing. So, in order to get the list of stadiums we must need some resources from where we can fetch our data. In real world, we fetch data from web services known as API. But in our case, we will create a JavaScript file which will contain our demo data and fetch data from there. Let’s create data.js file in your src folder. Add the following data:

const data = [ { "name": "Wembley Stadium", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Wembley_Stadium_interior.jpg/1024px-Wembley_Stadium_interior.jpg", "capacity": 90000, "priceCurrency": "EUR", "lat": 51.556181, "lng": -0.279465 }, { "name": "Old Trafford", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/4/43/Old_Trafford_inside_20060726_1.jpg", "capacity": 75653, "priceCurrency": "EUR", "lat": 53.463219, "lng": -2.291297 }, { "name": "Emirates Stadium", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Emirates_Stadium_east_side_at_dusk.jpg/1920px-Emirates_Stadium_east_side_at_dusk.jpg", "capacity": 60260 , "priceCurrency": "EUR", "lat": 51.555015, "lng": -0.108384 }, { "name": "London Stadium", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/f/f1/FloodlitLondonStadium.jpg", "capacity": 57000, "priceCurrency": "EUR", "lat": 51.538870, "lng": -0.016550 }, { "name": "City of Manchester Stadium", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/Etihad_Stadium.jpg/1024px-Etihad_Stadium.jpg", "capacity": 55097, "priceCurrency": "EUR", "lat": 53.481759, "lng": -2.202540 }, { "name": "Anfield", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Panorama_of_Anfield_with_new_main_stand_%2829676137824%29.jpg/1024px-Panorama_of_Anfield_with_new_main_stand_%2829676137824%29.jpg", "capacity": 54074, "priceCurrency": "EUR", "lat": 53.431066, "lng": -2.960819 } ] export default data

And in if you have an API then you can fetch data from the API in the following way

const url='path_to_you_json_data'; fetch(url) .then(response=>response.json()) .then((data)=>{ this.setState({ stadiums: data, allStadiums: data, }) })





Now, we have our data. Let's create our stadium component and add stadium.js and stadium.css file inside the components directory. Add the following code to your stadium.js file

import React from 'react' import './stadium.css' class Stadium extends React.Component{ render(){ const title= this.props.stadium.name+ this.props.stadium.capacity; const style={ backgroundImage:"url('"+ this.props.flat.imageUrl +"')" }; return( <div className="stadium"> <div className="stadium-picture" style={style}> </div> <div className="stadium-title"> {title} </div> </div> ); } } export default Stadium;





So, first we import React class. It just simply render with an image and a title. And, we know these data will come from our data.js file but how can we integrate the data. Lets add the following code to your App.js file just before render function.

constructor(props){ super(props); this.state ={ stadiums:[], allStadiums:[], selectedStadium: null, search: '' } } componentDidMount(){ this.setState({ stadiums: data, allStadiums: data }) }





It is obvious that we will have a list of stadiums and initially it will be empty. Ignore all the other variables for now. Here, we define a componentDidMount function to fetch data. One thing to notice if we use another name for this function is it will not work because the componentDidMount function will automatically be called by the React. Now, let us inject the data into our stadium component. Add the following line to the div having class name stadiums in app.js file.

<div className="stadiums"> {this.state.stadiums.map((stadium) => { return <Stadium key={stadium.name} stadium={stadium} ></Stadium> })} </div>

This is how we inject data into the component. As you can see inside the stadium tag there are two properties named key and stadium. These are props through which we pass data to the child component. We have a filter function map which returns each stadium object from stadiums and pass the value to the stadium component. And from the stadium, we fetch those data using this.props.stadium.object-property. Now, let's add the following CSS code to your stadium.css file.

.stadium{ flex-basis: calc(50% - 20px); margin: 10px; cursor: pointer; } .stadium:hover{ opacity: .8; } .stadium-picture{ height: 200px; background-size: cover; background-position: center; }





Now our app will look like this:





It is very simple. Now, let's start creating our map component. It may sound scary like implementing google map but the good news is some good people are creating components just like us and make those components open source. So, we can just plug those components and start using it. So, how can we use those external components? Easy just search in google and you will get GitHub links. Go to those links and just follow the instructions. In our case to use google-map-react we simply install it by typing:

npm install --save google-map-react





It will be listed as a dependency. Go to your package.json file you will see google-map-react there. Let’s implement this. Add the following code to div named map in app.js file:

<GoogleMapReact center={center} zoom={5} > </GoogleMapReact>





It will not work yet. We need to import it by

import GoogleMapReact from 'google-map-react'





Now we have to define the center as our stadiums are all in London. So, I will create the map centering London and have a zoom level 5.Let's define the center and add the following code in your app.js file inside render function.

let center={ lat:51.527452, lng:-0.124975 };





Now our map will look like this





Now, let’s add a marker to the map. What we want is a marker for every flat in the map. So, we need a marker component. Create a marker component and marker.css file in your components. And add the following code to your marker.js file.

import React from "react" import "./marker.css" class Marker extends React.Component{ render(){ return <div className="marker">{this.props.text}</div> } } export default Marker;

Pretty easy. We will have a text on the marker and we will get the text value from its parent component through props. And let's add the following in our marker.css file

.marker{ width:40px; background-color: white; border: 1px solid black; border-radius: 5px; text-align: center; } .marker.selected{ background-color: yellow; border-color: black; }





Now let's show our marker component in our google map. Just add the following code in your GoogleMapReact tag in your app.js file :

{this.state.stadiums.map((stadium) => { return <Marker key={stadium.name} lat={stadium.lat} lng={stadium.lng} text={stadium.capacity} ></Marker> })}





More like getting the flat component right. Here, we will have a marker for each flat in the map on the basis of their latitude and longitude. And don’t forget to import component each time. Now, your app will look like this:





So, we have our Stadiums list and their location on the map. Now, we can play a little bit using the map. For now, nothing will happen when we click the individual stadium. We want to highlight the location of the stadium on click. It is just an onclick event. So, we have to add an onclick event at each stadium. To do these add these lines to our stadium.js file.

<div className="stadium" onClick={this.handleclick}>





So, we need a handleclick function. This function will look like:

handleclick=()=>{ this.props.handleClick(this.props.stadium) };

Here, handleclick function will set the props value to the selected flat. But, we don't have any props value named handleclick in our <Stadium> tag in app.js file. Let's add it

<div className="stadiums"> {this.state.stadiums.map((stadium) => { return <Stadium key={stadium.name} stadium={stadium} handleClick={this.selectStadium} ></Stadium> })} </div>





And also add selectedStadium function on order to get the selected stadium to our app

selectStadium=(stadium)=>{ this.setState({ selectedStadium:stadium }) };





So, when we click a stadium component at first the handleclick function in stadium.js pass the current stadium to handleclick props value and then we set the stadium as the selected stadium. One more thing we need to do is add selectedStadium to our state and initially set it to null. So, if we want to center the selected flat on the map then simply change the value of a center like this:

if (this.state.selectedStadium){ center={ lat: this.state.selectedStadium.lat, lng: this.state.selectedStadium.lng } }





Now, what if we want to give a color to the marker when it is clicked. So, we can give a className selected and then give it a color. But, it will not do what we are expecting, it will just color all the markers. So, for achieving this we need to add the class dynamically. In marker.js file add the following code:

render(){ let classes='marker'; if(this.props.selected){ classes+= ' selected'; } return <div className={classes}>{this.props.text}</div> }





Now, we have to add a props value to Marker tag in app.js file. Let's add it by following way:

return <Marker key={stadium.name} lat={stadium.lat} lng={stadium.lng} text={stadium.capacity} selected={stadium === this.state.selectedStadium} ></Marker>





So, by adding the selected props we can now color the marker for only selected stadium. One thing to be noticed is in the props value we have a key but it is actually for optimization purpose. In most of the cases, we should give the id but in our case as we don't have any id so we just add stadium.name to our key value. So, now our app will look like this:









So, the marker will turn to yellow when we click. So, we are nearly at the end of our goal. The last thing we want to add in our app is a search bar. The search will be just an input box where we will put strings and on the basis of that or those string, the flats will be shown.

So, add the following code to search div in app.js file:

<input type='text' placeholder="Search.." />





Let's add some CSS to it. Add the following code to app.css file

.search{ padding: 10px; } .search input{ width: 100%; height: 40px; font-size: 24px; }





At this condition our search will not do anything. Add the following attribute in input tag:

<input type='text' placeholder="Search.." value={this.state.search} onChange={this.handleChange} />





So, we have to add search in state and an event named onChange which will call handleChange function. Let’s add the function:

handleChange=(event)=>{ this.setState({ search: event.target.value, stadiums: this.state.allStadiums.filter((stadium)=> new RegExp(this.state.search,'i').exec(stadium.name)) }); };

Now, the search will look like this









Here, we get the search value using event.target.value and on the basis of that search value we filter the list of stadiums. Here you can see that we have added another state variable named allStadiums. Initially, we got all the stadiums and stored in a list named flats. But in the case of search, our stadiums’ number will change on the basis of search value. So, in componentDidMount, we also store all our flats in a state variable called allFlats. Then on the basis of the search value, we filter allFlats and put the resulted flats in flats list. And all done. Have a deep breath, we have covered a lot of things.