# HINTS TO USE CARTO AND AIRSHIP IN REACT
created by Jabal Logian @w3yu2Di_T6-vNOV6L6w63A
Instagram, Github, Gitlab, LinkedIn: @jaballogian
## 0. Project Examples
1. [my github project](https://github.com/jaballogian/learn-react-carto-airship)
2. [category widget component](https://github.com/jaballogian/learn-react-carto-airship/tree/master/src/Components/Category%20Widget)
3. [layout examples](https://github.com/jaballogian/learn-react-carto-airship/tree/master/src/Examples)
## 1. Dependencies
### Install necessary dependencies using `npm install` command such as:
npm install @carto/airship-components
npm install @carto/airship-icons
npm install @carto/airship-style
npm install @carto/carto.js
npm install @carto/carto-vl
npm install carto
npm install leaflet
npm install mapbox-gl
npm install react-leaflet
## 2. Index.js file
### Erase React Strict Mode in the `index.js` file (inside src folder)
Before:
```javascript=
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
```
After:
```javascript=
ReactDOM.render(
<App />,
document.getElementById('root')
);
```
## 3. Index.html file
### If want to use mapbox map, add this line of code in the `index.html` file (inside public folder) inside `<head>` tag
```htmlembedded=
<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css" rel="stylesheet" />
```
### If want to use carto map, add these line of codes in the `index.html` file (inside public folder) inside `<head>` tag
```htmlembedded=
<link href="https://carto.com/developers/carto-js/examples/maps/public/style.css" rel="stylesheet"></link>
<link href="https://carto.com/developers/carto-vl/v1.4.4/examples/maps/style.css" rel="stylesheet">
```
### If want to use leaflet map, add these line of codes in the `index.html` file (inside public folder) inside `<head>` tag
```htmlembedded=
<link href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" rel="stylesheet">
```
## 4. React Functional Component
### 4.1 Create react functional component
```javascript=
import React from 'react'
function ComponentName(){
return(<div></div>)
}
export default ComponentName
```
### 4.2 Import Carto and Airship libraries (css, icons, and components)
```javascript=
import '@carto/airship-style/dist/airship.css'
import '@carto/airship-icons'
import { defineCustomElements } from '@carto/airship-components/dist/loader'
defineCustomElements(window)
```
### 4.3 Import mapbox map library in react component file if want to use mapbox map
```javascript=
import mapboxgl from 'mapbox-gl'
```
### 4.3 If want to use carto map, import carto map library in react component file
```javascript=
import L from 'leaflet'
import carto from '@carto/carto.js'
```
## 5. HTML code section
### 5.1 Copy HTML codes from Carto/Airship documentation (included starting and closing `<body>` tags) and paste them inside `return()` of react functional component created
Documentation:
```htmlembedded=
<body class="as-app-body as-app">
..... copy everything including the "body" tags
</body>
```
Your react component:
```javascript=
function ComponentName(){
return(
..... paste the code here
)
}
```
### 5.2 Change HTML code to HTML-in-JS code
For example
Before:
```htmlembedded=
<input type="checkbox" name="checkbox-0">
<hr>
```
After:
```htmlembedded=
<input type="checkbox" name="checkbox-0"/>
<hr/>
```
### 5.3 Change all "class" props to "className" props
For example
Before:
```htmlembedded=
<body class="as-app-body as-app"></body>
```
After:
```htmlembedded=
<body className="as-app-body as-app"></body>
```
### 5.4 Change `<style="property1: value1; property2: value2, .....">` props to `style={{property1: "value1", property2: "value2", .....}}`
For example
Before:
```htmlembedded=
<a style="position: absolute; right: 12px; top: 12px;">Close</a>
```
After:
```htmlembedded=
<a style={{position: "absolute", right: "12px", top: "12px"}}>Close</a>
```
### 5.5 Change `id="id-name"` props to `ref={idName}` (from useRef() hook) props if you want to control component
For example
Before:
```htmlembedded=
<button id="js-button-modal">
```
After:
```htmlembedded=
<button ref={jsButtonModal}>
```
### 5.6 Change `for` props to `htmlFor` props
For example
Before:
```htmlembedded=
<label for="first">First</label>
```
After:
```htmlembedded=
<label htmlFor="first">First</label>
```
### 5.7 Change `tabindex` props to `tabIndex` props
For example
Before:
```htmlembedded=
<ul tabindex="-1"></ul>
```
After:
```htmlembedded=
<ul tabIndex="-1"></ul>
```
### 5.8 Change `readonly` props to `readOnly` props
For example
Before:
```htmlembedded=
<input readonly/>
```
After:
```htmlembedded=
<input readOnly/>
```
**Don't forget to read for all error props messages in the browser console and fix them**
## 6. CSS section
### 6.1 Copy CSS codes from Carto/Airship documentation (inside `style` tags) and paste them inside react functional component created
Documentation:
```htmlembedded=
<style>
..... copy everything inside "style" tags
</style>
```
Your react component:
```javascript=
function ComponentName(){
..... paste the code here
}
```
### 6.2 Create constant variable for each styling element and change to CSS-in-JS convention (from `property-name: value;` to `propertyName: "value"`)
For example
Documentation:
```htmlembedded=
<style>
as-infowindow {
position: absolute;
top: 30px;
left: 30px;
}
.as-map-area {
background-color: #B5E0F9;
}
</style>
```
Your react component:
```javascript=
function ComponentName(){
const asInfowindow = {
position: "absolute",
top: "30px",
left: "30px"
}
const asMapArea = {
backgroundColor: "#B5E0F9"
}
return(<div></div>)
}
```
**Don't forget to implement the style using the `style={styleName}` prop in the component opening tag**
For example
```htmlembedded=
<div style={asMapArea}></div>
```
## 7. JavaScript section
### 7.1 Copy JavaScript code from Carto/Airship documentation (inside `script` tags) and paste them inside react functional component created
Documentation:
```htmlembedded=
<script>
..... copy everything inside "script" tags
</script>
```
Your react component:
```javascript=
function ComponentName(){
..... paste the code here
}
```
### 7.2 Replace `document.querySelector()` method using `useRef()` hook from `react` dependency
Import `useRef()` from `react` dependency
```javascript=
import {useRef} from 'react'
```
For example
Before:
```javascript=
var rangeSliderWidget = document.querySelector('as-range-slider')
```
After (put directly inside functional component):
```javascript=
function ComponentName(){
const rangeSliderWidget = useRef()
}
```
**Don't forget to add `ref={variableName}` props to component opening tag**
For example
```htmlembedded=
<as-range-slider ref={rangeSliderWidget}></as-range-slider>
```
### 7.3 Add `.current` to all `useRef` variables
For example
Before:
```javascript=
rangeSliderWidget.minValue = 10
```
After:
```javascript=
rangeSliderWidget.current.minValue = 10
```
### 7.4 Use `useEffect()` hook from `react` dependency to load data for all components after rendering them
Import `useEffect()` from `react` dependency
```javascript=
import {useEffect} from 'react'
```
For example
Before:
```javascript=
function onLoad () {
feedRangeSlider();
feedDropdown();
feedHistogram();
feedCategories();
setModal();
};
```
After:
```javascript=
useEffect(() => {
feedRangeSlider()
feedDropdown()
feedHistogram()
feedCategories()
}, [])
```
### 7.5 Create stand alone function to handle on click button
For example
Before:
```javascript=
jsButtonModal.addEventListener('click', function() {
jsModal.classList.remove('as-modal--hidden');
jsModal.classList.add('as-modal');
});
```
After:
```javascript=
function jsButtonModalOnClick(){
jsModal.current.classList.remove('as-modal--hidden');
jsModal.current.classList.add('as-modal');
}
```
**Don't forget to add `onClick={OnClickFunction}` props in the component opening tag**
For example
```htmlembedded=
<button ref={jsButtonModal} onClick={jsButtonModalOnClick}>
```