Single Page Application Sederhana dengan React + Tachyons

Tulisan ini melanjutkan pembahasan tentang pembelajaran React melalui CRA pada tulisan sebelumnya. Secara garis besar pembahasan sebelumnya hanya pengenalan React melalui CRA dan instalasi CRA. Setelah install CRA, secara default direktori project akan berisi direktori dan file seperti berikut :

Di dalam main directory project kita (sebut saja ‘my-blog’) terdapat 3 direktori./node_modules yang berisi seluruh package node lokal yang ditambahkan saat instalasi CRA melalui package manager (NPM/yarn). /public berisi halaman index yang akan ditampilkan pertama kali saat aplikasi dijalankan. /src umumnya akan berisi komponen-komponen yang akan ditampilkan di halaman aplikasi. Seluruh package yang diinstal secara lokal pada aplikasi akan tersimpan pada package.json dengan berbagai spesifikasi (nama & versi) package yang digunakan.

Implementasi

Goals-nya tulisan ini adalah implementasi main concept pada React yaitu JSX, Rendering Elements, dan React Component. Sebetulnya, main concept React agak sedikit banyak, tapi pada kesempatan ini tujuan dari tulisan ini adalah membangun SPA statis dimana data dinamis belum digunakan.

Untuk kostumasi CSS, disini kita gunakan toolkit css Tachyons. Kalau mau gunakan framework CSS lainnya tidak masalah. Tachyons dapat di-include dengan copy-paste link ini di file index.html pada direktori /public :
<link rel="stylesheet" href="https://unpkg.com/tachyons@4.10.0/css/tachyons.min.css"/>

Component

Aplikasi React tersusun atas komponen-komponen yang disatukan (component-based). Komponen yang dibangun dapat digunakan lagi untuk keperluan halaman lainnya (reusable). Pada kesempatan ini komponen yang akan dibangun sebagai berikut :

  • Header (Header.js) -> Menu navigation
  • Hero (Hero.js) -> Banner Component
  • Content (Content.js) -> Bagian isi
  • App (App.js) -> Bagian utama

Oke, pertama-tama buat sebuah komponen pada folder /src dengan nama file Header.js :

import React from 'react'
const Header = () => (
<div>
<header class="fixed w-100 ph3 pv3 pv4-ns ph4-m ph5-l sans-serif">
<nav className='fr f6 fw6 ttu tracked'>
<a className='link dim white dib mr4' href='#' title='Home'>Home</a>
<a className='link dim white dib mr4' href='#' title='About'>About</a>
<a className='link dim white dib pr5' href='#' title='Contact'>Contact</a>
</nav>
</header>
</div>
)
export default Header
  • Bagian pertama, import perlu dilakukan untuk mengimpor module React.
  • Variabel const Header untuk untuk mendefinisikan component (akan dibahas selanjutnya).
  • Bagian akhir, export default untuk memberikan fungsi reusable pada component.

Kemudian tambahkan komponen lainnya pada folder/src dengan nama file Hero.js :

import React from 'react'
import Header from './Header'
const imgUrl = 'https://images.unsplash.com/photo-1493934558415-9d19f0b2b4d2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1472&q=80'
const style = {
backgroundImage: 'url(' + imgUrl + ')',
}
const Hero = () => (
<div className='cf cover bg-left bg-center-l' style={style}>
<div className='cf bg-black-60 white'>
<Header />
<h2 className='mv7 ml3 f2 fl'>Selamat Datang, Nyamuk Kebon!</h2>
</div>
</div>
)
export default Hero
  • Bagian pertama, import perlu dilakukan selain untuk mengimpor module React, komponen Header juga perlu diimpor karena komponen Header akan disisipkan pada komponen ini.
  • Variabel const imgUrl berisi link gambar background pada component.
  • Variabel const style untuk menyimpan script custom CSS secara internal style sheet.
  • Variabel const Hero untuk mendefinisikan component.
  • Bagian akhir, export default untuk memberikan fungsi reusable pada component.

Kemudian tambahkan komponen lainnya pada folder/src dengan nama file Content.js :

import React, { Component } from 'react'
const imgUrl = 'http://mrmrs.github.io/photos/12.jpg'
const style = {
background: 'url(' + imgUrl + ') no-repeat center center fixed',
backgroundSize: 'cover',
}
class Content extends Component {
render() {
return (
<article data-name="article-full-bleed-background">
<div class="cf" style={style}>
<div class="fl pa3 pa4-ns bg-white black-70 measure-narrow f3 times">
<header class="bb b--black-70 pv4">
<h3 class="f2 fw7 ttu tracked lh-title mt0 mb3 avenir">Lorem Ipsum</h3>
<h4 class="f3 fw4 i lh-title mt0">What is Lorem Ipsum?</h4>
</header>
<section class="pt5 pb4">
<p class="times lh-copy measure f4 mt0">
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type specimen book.
It has survived not only five centuries, but also the leap into electronic typesetting,
remaining essentially unchanged.
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
</section>
</div>
</div>
</article>
)
}
}
export default Content
  • class Content extends Component merupakan Class Component yang tidak jauh beda fungsinya seperti variable const Hero mauput const Header. Karena tujuan utamanya sama-sama untuk mendefinisikan component.

Kemudian, sedikit modifikasi pada bagian utama :

import React, { Component } from 'react';
import './App.css';
import Hero from './Hero'
import Content from './Content'
class App extends Component {
render() {
return (
<div className='App'>
<Hero />
<Content />
</div>
);
}
}
export default App;

By the way, Component utama ini akan di-render langsung sebagai multiple element oleh ReactDOM.render() pada DOM utama pada index.html yaitu <div id=”root”></div>.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="https://unpkg.com/tachyons@4.10.0/css/tachyons.min.css"/>
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

Secara default, ReactDOM.render() pada CRA akan dijumpai pada file index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();

Breakdown Component

Cara untuk mendefinisikan Component pada React ada 2, yaitu dengan Function Component dan Class Object. Secara garis besar, function component hanya sebuah fungsi Javascript yang dapat mendefinisikan component, memiliki performa lebih cepat dari class object, lebih sedikit kode yang ditulis, namun tidak dapat menggunakan setState() pada function.

Sedangkan class object agak sedikit memerlukan lebih banyak kode dan harus meng-extend module component. Selain itu, React memberikan kelebihan pada class object dengan adanya Lifecycle Hooks.

JSX & Rendering Elements

JSX merupakan syntax extension pada JavaScript dan digunakan untuk mengimplementasikan UI pada aplikasi React. Penggunaan JSX tidak diwajibkan namun sangat dianjurkan penggunaannya pada React. Nah, JSX inilah yang sanggup menciptakan elements pada DOM.

Contoh simpel dari penempatan elemen pada JSX adalah sebagai berikut:

const name = 'John Metal';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
element,
document.getElementById('root')
);

Hasilnya akan menampilkan syntax<h1>Hello, {name}</h1> .

Elements yang sudah ditempatkan JSX nantinya akan di-render oleh ReactDOM.render();

Adapun yang lebih rumit dari contoh tersebut seperti pada kode kita sebelumnya :

const Hero = () => (
<div className='cf cover bg-left bg-center-l' style={style}>
<div className='cf bg-black-60 white'>
<h2 className='mv7 ml3 f2 fl'>Selamat Datang, Nyamuk Kebon!</h2>
</div>
</div>
)
ReactDOM.render(
Hero,
document.getElementById('root')
);

Catatan : Element yang di-render lebih dari satu element harus di-wrap dengan <div></div> atau DOM lainnya.

Oke, cukup disini dulu kalau ada kesalahan dalam tiap penulisan ini mohon dikoreksi, Terima kasih.

This boilerplate on my github : https://github.com/alvinisasi/react-components-implement

Reference