Logo Universitas

Universitas ASA Indonesia

Program Studi: Teknologi Informasi

Mata Kuliah: Pengembangan Aplikasi Web Lanjut

SKS: 3 (2 teori, 1 praktikum)

Dosen Pengampu: Istiqomah Sumadikarta, S.T., M.Kom.

Beranda Mundur Maju

Pertemuan 5: Front End - Pengenalan ES6 dan React JS

JavaScript ES6


ES6 merupakan singkatan dari ECMAScript versi 6, yang mana dirilis pada tahun 2015. Jadi jika di internet menemui kata ES 2015 atau ES6 itu sama saja, jadi jangan bingung. ECMAScript adalah sebuah standarisasi scripting language (Javascript) yang dibuat oleh European Computer Manufacturers Association (ECMA).

Dengan hadirnya ES6, maka di dalam JavaScript kini memiliki fitur baru dan penulisan yang lebih singkat dibandingkan JavaScript versi sebelumnya yaitu ES5 yang dirilis pada tahun 2009.

Dan untuk menjalankan kode yang ditulis menggunakan ES6, baiknya kita harus menggunakan program tambahan yang bernama Node.js. Untuk menjalankan kode yang ditulis menggunakan ES6 kita bisa menjalankan di dalam terminal dengan cara seperti berikut ini :

buat file baru dengan nama hello-world.js. Dan masukkan kode berikut ini.

const text = 'Learning ES6'

console.log(text);

Dan untuk menjalankan, cukup ketik di dalam CMD/terminal seperti ini.

node hello-world.js

> Learing ES6	//<-- output

Jadi sebelum kita belajar React.js dengan lebih mudah dan nyaman, sebaiknya kita harus tau dulu dasar-dasar di dalam ES6, seperti membuat variable, Arrow Function, Spread Operator dan lain-lain. Di dalam bab ini kita akan belajar tentang JavaScript ES6 terlebih dahulu, meskipun tidak semua kita bahas tapi sudah cukup untuk meng-cover apa yang kita butuhkan.

Variable di dalam ES6


Jika sebelumnya sudah pernah belajar JavaScript, maka kita tahu bahwa di dalam JavaScript untuk membuat sebuah variable kita bisa menggunakan keyword var. Tapi di dalam ES6 kita mendapatkan keyword baru untuk membuat sebuah variable. Yaitu const dan let.

Keyword const

Keyword const merupakan variable yang nilainya tetap dan tidak bisa dirubah, contohnya seperti berikut ini :

//define variable
const name = 'Fika Ridaul Maulayya';

//try to change
name = 'SantriKoding';

Jika kode di atas dijalankan, maka akan mendapatkan error seperti berikut ini :

Uncaught TypeError: Assignment to constant variable.

Error tersebut muncul karena variable name tidak bisa diubah nilainya.

Keyword let

Keyword let lebih mirip dengan var, dimana nilainya bisa diganti-ganti sesuai dengan keinginan. Tapi tetap ada bedanya, yaitu pada scope di definisikannya.

Variable yang dibuat menggunakan let dan const menganut sistem block scope, yang mana cakupan variabelnya hanya bisa diakses di dalam blocknya saja.

Sedangkan var menganut sistem functional scope, yang artinya variable yang didefinisikan dapat diakses dari dalam maupun luar block scope (kecuali diluar function).

var name = 'Fika Ridaul Maulayya';

if(true) {
	var name = 'Ahmad';
	console.log(name); //<-- output "Ahmad"
}

console.log(name); // <-- output "Ahmad"

Di atas, hasilnya akan mencetak Ahmad, karena variable name di dalam if mengalami yang namanya override atau biasa disebut dengan hoisting/pengangkatan. jadi seolah-olah kode-nya menjadi seperti berikut ini :

var name = 'Fika Ridaul Maulayya';
var name = 'Ahmad';

if(true) {
	console.log(name); //<-- output "Ahmad"
}

console.log(name); // <-- output "Ahmad"

Nah, untuk mengatasi problem ini kita bisa menggunakan keyword let dengan tujuan agar tidak ada hoisting. Jadi variable name yang berada di luar dan dalam block if tidak akan tabrakan.

var name = 'Fika Ridaul Maulayya';

if(true) {
	let name = 'Ahmad';
	console.log(name); //<-- output "Ahmad"
}

console.log(name); // <-- output "Fika Ridaul Maulayya"

CATATAN : jika variable yang dibuat menggunakan var, let dan const tidak ditentukan block scope-nya, maka otomatis bersifat global dan bisa diakses dimana saja.

Default Parameter


Kita bisa membuat sebuah function yang memiliki parameter yang bersifat opsional. Dimana jika tidak ditentukan nilainya, maka kita akan berikan nilai secara default.

Sebelum ada ES6 untuk membuat parameter yang bersifat opsional di dalam function, kita bisa membuatnya seperti berikut ini :

function hello(message) {

	let message = message || 'Hello World!';
	
	console.log(message);

}

//panggil function tanpa parameter
console.log(hello()); // <-- output "Hello World!"

//panggil function dengan parameter
console.log(hello('Belajar ES6')); //<-- output "Belajar ES6"

Sekarang, di dalam ES6 kita bisa mempersingkat penulisannya sehingga menjadi lebih mudah dan cepat. Kurang lebih seperti berikut ini :

function hello(message = 'Hello World!') {

	console.log(message);

}

//panggil function tanpa parameter
console.log(hello()); // <-- output "Hello World!"

//panggil function dengan parameter
console.log(hello('Belajar ES6')); //<-- output "Belajar ES6"

Di atas, kita bisa memberikan default nilai parameter di dalam functionnya.

Template String


Template String atau Template Literal adalah cara atau teknik yang digunakan untuk memanggil sebuah variable di dalam string. Dan kita harus menggunakan backtick (``).

Contoh menggabungkan string dan variable tanpa template string, kurang lebih seperti berkut ini :

let name = 'Fika Ridaul Maulayya';

let gender = 'Laki-laki';

console.log(name + 'memiliki jenis kelamin : ' + gender); 
//output "Fika Ridaul Maulayya memiliki jenis kelamin : Laki-laki"

Dan kita bisa lebih mudah menuliskannya menggunakan template string, kurang lebih menjadi seperti berikut ini :

let name = 'Fika Ridaul Maulayya';

let gender = 'Laki-laki';

console.log(`${name} memiliki jenis kelamin : ${gender}`); 
//output "Fika Ridaul Maulayya memiliki jenis kelamin : Laki-laki"

Secara output hasilnya akan sama, dimana penulisannya sekarang lebih singkat dan mudah. Karena untuk menampilkan variable kita hanya menggunakan sintaks ${ namaVariable } di dalam backtick (``).

Arrow Function


Arrow function merupakan fitur bawaan sejak ES6 rilis, dimana digunakan untuk mempersingkat penulisan sebuah function menjadi =>.

Contoh dalam menulis function biasa.

//define function
const hello = function (name) {

	return `Hello ${name}`;

}

//panggil function
hello('Fika Ridaul Maulayya') //< -- output "Hello Fika Ridaul Maulayya"

Jika function di atas diubah menjadi arrow function, maka penulisannya akan menjadi lebih singkat lagi, kurang lebih seperti berikut ini :

//define function
const hello = name => `Hello ${name}`;

//panggil function
hello('Fika Ridaul Maulayya') //< -- output "Hello Fika Ridaul Maulayya"

Di atas contoh dalam menggunakan arrow function jika masih memiliki 1 parameter, bagaimana jika memiliki lebih dari 1 parameter?, kita bisa menambahkan pakai tanda kurung. Contohnya seperti berikut ini :

//define function
const hello = (name, umur) => `Hello ${name} umur ${umur}`;

//panggil function
hello('Fika Ridaul Maulayya', 25) //< -- output "Hello Fika Ridaul Maulayya umur 25"

Jika kita memiliki function yang nilai baliknya berupa object, maka kita harus membungkus body-nya menggunakan tanda kurung. Contohnya seperti berikut ini :

//define function
const hello = (name, umur) => ({
	status: 'OK',
	mesaage: `Hello $name umur ${umur}`
});

Terus bagaimana jika di dalam function tersebut memiliki lebih dari 1 baris kode? kita bisa membungkus body function menggunakan kurung kurawal. Kurang lebih seperti berikut ini :

//define function
const hello = name => {

	if(!name) {
		console.log('Name is required');
	}
	
	return `Hello ${name}`;

}

Rest Parameter


Rest Parameter digunakan jika kita ingin membuat sebuah function yang memiliki jumlah parameter yang tak terbatas. Rest Parameter ditandai dengan ... di dalam parameter.

Contohnya seperti berikut ini :

function sum(...rest) {
  let sum = 0;
  for (let number of rest) sum += number;
  return sum;
}

let x = sum(4, 9, 16, 25, 29, 100, 66, 77); // <-- output "326"

Di atas, kita bisa memberikan nilai berapaun di dalam variable x dan akan otomatis dijumlahkan terus di dalam function sum. Karena di dalam function sum kita berikan parameter berupa Rest Parameter.


Rest Parameter juga bisa digabung dengan parameter lainnya, dengan catatan harus ditaruh dipaling belakang di dalam parameter. Contohnya seperti berikut ini :

function sum(initVal, ...rest) {
  let sum = 0;
  for (let number of rest) sum += number;
  return initVal + sum;
}

let x = sum(10, 5); // <-- output "15"

Di atas, di dalam parameter kita berikan parameter pertama dengan nama initVal dan parameter kedua adalah ...rest.

Dan jika kita panggil function tersebut di dalam variable x dengan memberikan 2 parameter, yaitu 10 dan 5. Maka hasilnya adalah 15.

Destructuring & Restructuring


Destructuring Assigment

Destructuring digunakan untuk membuat sebuah variable-variable baru dari element yang ada di dalam sebuah array atau object.

Contoh destructuring di dalam array.

//array
const arr = ['Fika', 'Ahmad', 'Lutfi'];

//destructuring
const [name1, name2, name3] = arr;

//print output
console.log(name1); // <-- "Fika"
console.log(name3); // <-- "Ahmad"
console.log(name3); // <-- "Lutfi"

Di atas, pertama kita membuat sebuah array dengan nama arr, setelah itu kita destructuring atau extract menjadi sebuah variable-variable baru.


Contoh destructuring di dalam object.

//object
const obj = {
	name: 'Fika Ridaul Maulayya',
	age: 25
};

//destructuring
const {name, age} = obj;

//print ouput
console.log(name); // <-- "Fika Ridaul Maulayya"
console.log(age);  // <-- "25"	

Restructuring Assigment

Nah, kalau Restructuring ini kebalikan dari Destructuring, yaitu digunakan untuk membuat sebuah object dari variable.

Contohnya seperti berikut ini :

//define variable
const name = 'Fika Ridaul Maulayya';
const age = 25;

//restructuring
const obj = {name, age};

//print output
console.log(obj); // <-- {name: 'Fika Ridaul Maulayya', age: 25}

Spread Operator


Spread Operator ditandai dengan ... (titik tiga), dan digunakan untuk beberapa keperluan, yang pertama untuk meng-copy sebuah array dan yang kedua menggabungkan sebuah array.

Berikut ini contoh Spread Operator untuk meng-Copy array.

//define array 1
const arr1 = [1, 2, 3, 4, 5];

//define array 2
const arr2 = [...arr1];

//print output
console.log('array 1', arr1); // <-- [1, 2, 3, 4, 5];
console.log('array 2', arr2); // <-- [1, 2, 3, 4, 5];

Di atas, kita membuat variable arr1 dengan isi array 1-5. Kemudian kita buat variable baru dengan nama arr2 yang mana isinya meng-Copy dari variable arr1 menggunakan Spread Operator ...arr1.


kemudian kita berikan contoh untuk menggabungkan array menggunakan Spread Operator.

//define array 1
const arr1 = [1, 2, 3];

//define array 2
const arr2 = [4, 5, 6];

//define array 3
const arr3 = [...arr1, ...arr2];

//print array 3
console.log(arr3); // <-- [1, 2, 3, 4, 5, 6];

Di atas, pertama kita buat variable dengan nama arr1 yang berisi angka 1-3. Kemudian kita buat variable baru lagi dengan nama arr2 yang berisi angka 4-6.

Setelah itu, kita buat variable baru yang bernama arr3 yang berisi variable arr1 dan arr2 menggunakan Spread Operator. Jadi isi di dalam arr3 adalah penggabungan antara arr1 dan arr2.

Dan jika dijalankan, maka hasilnya adalah angka 1, 2, 3, 4, 5, 6.

Array.map


Array.map digunakan untuk mmbuat perulangan dari sebuah array dengan mengembalikan array baru tanpa memodifikasi array sumbernya. Array.map akan sering kita gunakan nantinya di dalam project React.js untuk melakukan perulangan data.

Berikut ini contoh menggunakan Array.map.

//define array
const arr = [1, 2, 3, 4, 5, 6, 7];

//looping
const number = arr.map( value => {
  return value;
});

//print output
console.log(number); // [1, 2, 3, 4, 5, 6, 7]

Di atas, pertama kita membuat variable arr dengan isi angka 1-7 dengan jenis array. Kemudian kita looping menggunakan arr.map() dan key yang kita gunakan untuk mendapatkan datanya adalah value.

kemudian kita print hasilnya dengan memanggil variable number, maka hasilnya akan tetap sama.

Promise


Promise adalah object yang mempresentasikan sebuah keberhasilan / kegagalan dari sebuah event yang bersifat asynchronus dan terjadi di masa yang akan datang. Dan karena dinamakan promise atau kalau diterjemahkan adalah janji, maka pasti ada kondisi yaitu terpenuhi dan tidak terpenuhi dari jani tersebut.

Dan di dalam promise ada 3 buah state yang harus kita tahu, yaitu

  1. fullfilled - keadaan yang terpenuhi.
  2. rejected - keadaan yang tidak terpenuhi.
  3. pending - yaitu waktu tunggu dari kedua keadaan di atas.

Dan untuk menjalankan keadaan di atas, maka ada sebuah callback yang bisa kita gunakan, yaitu resolve yang berarti janji telah terpenuhi. Dan reject ketika ada janji tidak terpenuhi. Kemudian ada finally yaitu ketika waktu tunggu selesai, baik keadaan tersebut terpenuhi atau tidak.

Dan di dalam promise ada sebuah aksi yang bisa kita jalankan ketika kondisi tersebut terpenuhi (resolve) yaitu menggunakan then. Dan jika tidak terpenuhi (reject) yaitu menggunakan catch.

Contohnya sederhanya seperti berikut ini :

//define variable
let done = true;

//define a promise
const task = new Promise((resolve, reject) => {

	if(done) {
		
		resolve('Task berhasil diselesaikan');
		
	} else {
		
		reject('Task belum diselesaikan');
	
	}

});

// run promise
console.log(task); // <-- ouput "Task berhasil diselesaikan"

Di atas kita masih mendapatkan nilai dalam bentuk promsie, bagaimana jika kita ingin mengambil nilai resolve dan reject-nya secara langsung ? Yups, kita bisa menggunakan then dan catch. Kurang lebih seperti berikut ini :

//define variable
let done = true;

//define a promise
const task = new Promise((resolve, reject) => {

	if(done) {
		
		resolve('Task berhasil diselesaikan');
		
	} else {
		
		reject('Task belum diselesaikan');
	
	}

});

// run promise with action
task
	.then(response => console.log(response))
	.catch(response => console.log(response))

Sekarang jika dijalankan, maka kita sudah bisa mengambil value-nya secara langsung.

Async Await


Async Await adalah fitur baru yang hadir sejak dirilisnya ES2017. Fitur ini digunakan untuk menangani proses promise dengan lebih singkat dan efisien.

Async atau Asynchronus Function merupakan sebuah fungsi yang bekerja secara asynchronus (melelui event loop), yang menghasilkan sebuah promise sebagai return value-nya, dimana kode yang ditulis seperti kode yang bersifat synchronus (standart).

Sebuah Async Function dapat memiliki keyword await di dalamnya, yang digunakan untuk memberhentikan eksekusi sementara sambil menunggu promise-nya selesai atau resolve.

Contohnya seperti berikut ini :

//define a promise with 3 seconds
const taskPromise = () => {
	return new Promise(resolve => {    
		setTimeout(() => resolve('Selesai'), 3000)  
	})
}

//define function "task" with async
const task = async () => {
	const done = await taskPromise();
	console.log(done);
}

//print
console.log('Mulai');
task();
console.log('Akhir');

Di atas, pertama kita buat sebuah promise yang melakukan return berupa resolve dengan text Selesai dalam waktu 3000 milli seconds atau 3 detik.

return new Promise(resolve => {    
	setTimeout(() => resolve('Selesai'), 3000)  
})

Kemudian kita buat function baru dengan nama task dengan jenis asynchronus, yaitu di tandai dengan keyword async. Dan di dalamnya kita buat variable baru dengan nama done yang berisi keyword await yang memanggil promise taskPromise.

const task = async () => { // <--  add async keyword

	const done = await taskPromise();	// <-- add await keyword
	...

Kemudian kita panggil function async tersebut dengan urutan kedua. Dan hasilnya akan ditampilkan setelah 3 detik.

console.log('Mulai');

task(); // <-- async

console.log('Akhir');

Output :

Mulai
Akhir
Selesai //setelah 3 detik

Apa itu React.js ?


React adalah library JavaScript yang sangat populer dan digunakan untuk membangun sebuah user interface dengan dinamis dan reaktif. React sendiri dibuat oleh perusahaan raksasa, yaitu Facebook dan sekarang sudah dibantu oleh banyak developer diseluruh dunia.

Sebenarnya React pertama kali dibuat oleh salah satu software developer dari Facebook, yaitu Jordan Walke. Yang mana setelah satu dekade memutuskan untuk keluar dari Facebook dan fokus mengembangkan perusahaannya sendiri dan React.js.

React banyak digunakan oleh perusahaan besar dalam membangun sebuah sistem atau website mereka, seperti website Facebook, Netflix, Airbnb, WhatsApp dan masih banyak lagi yang lain.

Tidak hanya di dunia, di Indonesia React juga sangat populer digunakan dan banyak perusahaan besar seperti Tokopedia, Shoope dan yang lain menggunakan React di dalam website mereka.

Makanya tidak rugi jika kita belajar React untuk sekarang dan di masa yang akan datang, karena kebanyakan industri memang mencari software developer yang bisa menggunakan React.

React pertama kali dirilis pada tahun 2013 dan berikut ini table rilis versi dari awal sampai tulisan ini dibuat.

Version Release Date Changes
0.3.0 29 May 2013 Initial Public Release
0.4.0 20 July 2013 Support for comment nodes <div>{/* */}</div>, Improved server-side rendering APIs, Removed React.autoBind, Support for the key prop, Improvements to forms, Fixed bugs.
0.5.0 20 October 2013 Improve Memory usage, Support for Selection and Composition events, Support for getInitialState and getDefaultProps in mixins, Added React.version and React.isValidClass, Improved compatibility for Windows.
0.8.0 20 December 2013 Added support for rows & cols, defer & async, loop for <audio> & <video>, autoCorrect attributes. Added onContextMenu events, Upgraded jstransform and esprima-fb tools, Upgraded browserify.
0.9.0 20 February 2014 Added support for crossOrigin, download and hrefLang, mediaGroup and muted, sandbox, seamless, and srcDoc, scope attributes, Added any, arrayOf, component, oneOfType, renderable, shape to React.PropTypes, Added support for onMouseOver and onMouseOut event, Added support for onLoad and onError on <img> elements.
0.10.0 21 March 2014 Added support for srcSet and textAnchor attributes, add update function for immutable data, Ensure all void elements don't insert a closing tag.
0.11.0 17 July 2014 Improved SVG support, Normalized e.view event, Update $apply command, Added support for namespaces, Added new transformWithDetails API, includes pre-built packages under dist/, MyComponent() now returns a descriptor, not an instance.
0.12.0 21 November 2014 Added new features Spread operator ({...}) introduced to deprecate this.transferPropsTo, Added support for acceptCharset, classID, manifest HTML attributes, React.addons.batchedUpdates added to API, @jsx React.DOM no longer required, Fixed issues with CSS Transitions.
0.13.0 10 March 2015 Deprecated patterns that warned in 0.12 no longer work, ref resolution order has changed, Removed properties this._pendingState and this._rootNodeID, Support ES6 classes, Added API React.findDOMNode(component), Support for iterators and immutable-js sequences, Added new features React.addons.createFragment, deprecated React.addons.classSet.
0.14.1 29 October 2015 Added support for srcLang, default, kind attributes, and color attribute, Ensured legacy .props access on DOM nodes, Fixed scryRenderedDOMComponentsWithClass, Added react-dom.js.
15.0.0 7 April 2016 Initial render now uses document.createElement instead of generating HTML, No more extra <span>s, Improved SVG support, ReactPerf.getLastMeasurements() is opaque, New deprecations introduced with a warning, Fixed multiple small memory leaks, React DOM now supports the cite and profile HTML attributes and cssFloat, gridRow and gridColumn CSS properties.
15.1.0 20 May 2016 Fix a batching bug, Ensure use of the latest object-assign, Fix regression, Remove use of merge utility, Renamed some modules.
15.2.0 1 July 2016 Include component stack information, Stop validating props at mount time, Add React.PropTypes.symbol, Add onLoad handling to <link> and onError handling to <source> element, Add isRunning() API, Fix performance regression.
15.3.0 30 July 2016 Add React.PureComponent, Fix issue with nested server rendering, Add xmlns, xmlnsXlink to support SVG attributes and referrerPolicy to HTML attributes, updates React Perf Add-on, Fixed issue with ref.
15.3.1 19 August 2016 Improve performance of development builds, Cleanup internal hooks, Upgrade fbjs, Improve startup time of React, Fix memory leak in server rendering, fix React Test Renderer, Change trackedTouchCount invariant into a console.error.
15.4.0 16 November 2016 React package and browser build no longer includes React DOM, Improved development performance, Fixed occasional test failures, update batchedUpdates API, React Perf, and ReactTestRenderer.create().
15.4.1 23 November 2016 Restructure variable assignment, Fixed event handling, Fixed compatibility of browser build with AMD environments.
15.4.2 6 January 2017 Fixed build issues, Added missing package dependencies, Improved error messages.
15.5.0 7 April 2017 Added react-dom/test-utils, Removed peerDependencies, Fixed issue with Closure Compiler, Added a deprecation warning for React.createClass and React.PropTypes, Fixed Chrome bug.
15.5.4 11 April 2017 Fix compatibility with Enzyme by exposing batchedUpdates on shallow renderer, Update version of prop-types, Fix react-addons-create-fragment package to include loose-envify transform.
15.6.0 13 June 2017 Add support for CSS variables in style attribute and Grid style properties, Fix AMD support for addons depending on react, Remove unnecessary dependency, Add a deprecation warning for React.createClass and React.DOM factory helpers.
16.0.0 26 September 2017 Improved error handling with introduction of "error boundaries", React DOM allows passing non-standard attributes, Minor changes to setState behavior, remove react-with-addons.js build, Add React.createClass as create-react-class, React.PropTypes as prop-types, React.DOM as react-dom-factories, changes to the behavior of scheduling and lifecycle methods.
16.1.0 9 November 2017 Discontinuing Bower Releases, Fix an accidental extra global variable in the UMD builds, Fix onMouseEnter and onMouseLeave firing, Fix placeholder, Remove unused code, Add a missing package.json dependency, Add support for React DevTools.
16.3.0 29 March 2018 Add a new officially supported context API, Add new packagePrevent an infinite loop when attempting to render portals with SSR, Fix an issue with this.state, Fix an IE/Edge issue.
16.3.1 3 April 2018 Prefix private API, Fix performance regression and error handling bugs in development mode, Add peer dependency, Fix a false positive warning in IE11 when using Fragment.
16.3.2 16 April 2018 Fix an IE crash, Fix labels in User Timing measurements, Add a UMD build, Improve performance of unstable_observedBits API with nesting.
16.4.0 24 May 2018 Add support for Pointer Events specification, Add the ability to specify propTypes, Fix reading context, Fix the getDerivedStateFromProps() support, Fix a testInstance.parent crash, Add React.unstable_Profiler component for measuring performance, Change internal event names.
16.5.0 5 September 2018 Add support for React DevTools Profiler, Handle errors in more edge cases gracefully, Add react-dom/profiling, Add onAuxClick event for browsers, Add movementX and movementY fields to mouse events, Add tangentialPressure and twist fields to pointer event.
16.6.0 23 October 2018 Add support for contextType, Support priority levels, continuations, and wrapped callbacks, Improve the fallback mechanism, Fix gray overlay on iOS Safari, Add React.lazy() for code splitting components.
16.7.0 20 December 2018 Fix performance of React.lazy for lazily-loaded components, Clear fields on unmount to avoid memory leaks, Fix bug with SSR, Fix a performance regression.
16.8.0 6 February 2019 Add Hooks, Add ReactTestRenderer.act() and ReactTestUtils.act() for batching updates, Support synchronous thenables passed to React.lazy(), Improve useReducer Hook lazy initialization API.
16.8.6 27 March 2019 Fix an incorrect bailout in useReducer(), Fix iframe warnings in Safari DevTools, Warn if contextType is set to Context.Consumer instead of Context, Warn if contextType is set to invalid values.
16.9.0 9 August 2019 Add React.Profiler API for gathering performance measurements programmatically. Remove unstable_ConcurrentMode in favor of unstable_createRoot
16.10.0 27 September 2019 Fix edge case where a hook update wasn't being memoized. Fix heuristic for determining when to hydrate, so we don't incorrectly hydrate during an update. Clear additional fiber fields during unmount to save memory. Fix bug with required text fields in Firefox. Prefer Object.is instead of inline polyfill, when available. Fix bug when mixing Suspense and error handling.
16.10.1 28 September 2019 Fix regression in Next.js apps by allowing Suspense mismatch during hydration to silently proceed
16.10.2 3 October 2019 Fix regression in react-native-web by restoring order of arguments in event plugin extractors
16.11.0 22 October 2019 Fix mouseenter handlers from firing twice inside nested React containers. Remove unstable_createRoot and unstable_createSyncRoot experimental APIs. (These are available in the Experimental channel as createRoot and createSyncRoot.)
16.12.0 14 November 2019 React DOM - Fix passive effects (useEffect) not being fired in a multi-root app.React Is - Fix lazy and memo types considered elements instead of components
16.13.0 26 February 2020 Features added in React Concurrent mode.Fix regressions in React core library and React Dom.
16.13.1 19 March 2020 Fix bug in legacy mode Suspense.Revert warning for cross-component updates that happen inside class render lifecycles
16.14.0 14 October 2020 Add support for the new JSX transform.
17.0.0 20 October 2020 "No New Features" enables gradual React updates from older versions.Add new JSX Transform, Changes to Event Delegation
17.0.1 22 October 2020 React DOM - Fixes a crash in IE11
17.0.2 22 March 2021 React DOM - Remove an unused dependency to address the SharedArrayBuffer cross-origin isolation warning.
18.0.0 29 March 2022 Concurrent React, Automatic batching, New Suspense Features, Transitions, Client and Server Rendering APIs, New Strict Mode Behaviors, New Hooks.
18.1.0 26 April 2022 Many fixes and performance improvements
18.2.0 14 June 2022 Many more fixes and performance improvements

Komponen dan Props di React.js


Di dalam React semua user interface atau antar muka aplikasi dibangun menggunakan komponen. Jadi kesannya seperti LEGO, dimana dari komponen-komponen kecil dikombinasikan menjadi komponen yang sangat besar. Dan komponen yang paling atas di dalam React disebut dengan root, yaitu mempresentasikan aplikasi secara keseluruhan.

Dengan menggunakan konsep ini, kita bisa membuat sebuah komponen yang bisa digunakan berulang kali (reusable) dibandingkan harus membuatnya secara berulang-ulang.

Secara konsep, komponen mirip dengan fungsi pada Javascript. Komponen menerima beberapa masukan (biasa disebut “props”) dan mengembalikan element React yang mendeskripsikan apa yang seharusnya tampil pada layar.

Di dalam react ada 2 cara untuk membuat sebuah komponen, yaitu menggunakan function component dan class component.

Function Component & Class Component

Cara paling sederhana untuk mendefinisikan sebuah komponen adalah dengan menuliskan sebuah function component:

function Welcome(props) {
  return <h1>Halo, {props.name}</h1>;
}

Fungsi ini adalah komponen React yang sah karena menerima sebuah “props” tunggal (yang bertindak sebagai props) atau argumen objek dengan data dan kembalian sebuah element React. Kita menyebut komponen karena itu benar-benar merupakan fungsi Javascript.

Kita juga dapat menggunakan sebuah ES6 class untuk mendefinisikan sebuah komponen:

class Welcome extends React.Component {
  render() {
    return <h1>Halo, {this.props.name}</h1>;
  }
}

Dari sudut pandang React, kedua komponen di atas mempunyai nilai yang sama. function dan class komponen mempunyai beberapa fitur tambahan yang biasa disebut dengan state dan lifecycle (akan dibahas di materi selanjutnya).

Props

Props atau singkatan dari properties, yang mana mirip seperti attribute tag di dalam HTML. Props biasanya digunakan untuk mengirimkan sebuah data dari parent component ke child component.

Props dengan Function Component

Dalam pembuatan sebuah props, jika kita menggunakan function component maka props tersebut adalah parameter-nya. Contohnya seperti berikut ini :

//component A mengirim data dengan props "message"
<ComponentA message="Hello World!" /> 


//function component
function ComponentA(props) { // <-- props sebagai parameter

	return(
		{/* print props "message" */}
		<p>{props.message}</p>
	)

}

Di atas, kita berikan contoh dalam pembuatan sebuah props di dalam function component, yaitu mengirimkan sebuah props yang bernama message dengan value Hello World!.

Dan di dalam componentA kita ambil props sebagai parameter dan kita baca nilainya di dalam method return dengan kode seperti ini props.message.


Props dengan Class Component

Sekarang, kita akan mencoba membuat props menggunakan class component. Jika menggunakan class component, untuk mengakses props-nya kita bisa menggunakan keyword this. kurang lebih seperti berikut ini :

//component B mengirim data dengan props "message"
<ComponentB message="Hello World!" /> 

//class component
class ComponentB extends React.Component {

	render(){
		{/* print props "message" with "this" */}
		return <p>{this.props.message}</p>;
	}

}

Di atas, untuk membaca props di dalam class component kita membutuhkan keyword yang bernama this.

JSX di React.js


Cobalah lihat deklarasi variabel dibawah ini:

const element = <h1>Halo, Dunia!</h1>;

Sintak tag aneh di atas bukanlah sebuah string ataupun HTML.

Sintak ini di kenal dengan sebutan JSX, dan sintak ini adalah sebuah sintaks ekstensi untuk JavaScript. Kita disarankan menggunakannya dengan React untuk mendeskripsikan bagimana antarmuka pengguna seharusnya terlihat.

Mengapa JSX?

React mengakui bahwa logika rendering akan secara inheren digabungkan dengan logika antarmuka pengguna lainnya. bagaimana events akan ditangani, bagaimana state berubah seiring dengan waktu, dan bagaimana data disiapkan untuk di tampilkan.

Dengan menggunakan JSX kita bisa menyelesaikan permasalahan tersebut dibandingkan harus membuat logika dan antar muka pengguna di file yang terpisah, karena kita bisa membuat keduanya secara bersamaan di dalam sebuah komponen.

React tidak mengharuskan kita untuk menggunakan JSX, namun kebanyakan orang merasa terbantu dengan adanya JSX sebagai bantuan visual saat mengerjakan antarmuka pengguna di dalam kode JavaScript. Menggunakan JSX juga memungkinkan React untuk menampilkan pesan kesalahan (error) dan peringatan (warning) yang lebih bermanfaat.

Dalam contoh di bawah ini, kita mendeklarasikan variabel bernama name dan kemudian menggunakannya di dalam JSX dengan cara membungkusnya di dalam tanda kurung kurawal (curly braces):

//define variable name
const name = 'Budi';

//panggil variable name
const element = <h1>Halo, {name}</h1>;

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

JSX Harus Punya Container

Di dalam JSX jika return-value memiliki lebih dari satu element harus dibungkus lagi dengan sebuah container. Bentuknya bisa menggunakan element HTML seperti <div>, React.Framgment atau Array.

Contohnya penulisan yang tidak benar seperti berikut ini :

function App() {

	return (
		<p> Belajar React </p>
		<p> di SantriKoding.com </p>
	)

}

Kode di atas akan menghasilkan sebuah error, yang kurang lebih seperti berikut ini :

/* Error: JSX expressions must have one parent element. */

Karena di dalam return-value terdapat lebih dari satu element tanpa ada sebuah container yang membungkusnya. Dan berikut ini beberapa contoh penulisan yang baik dan benar.

Menggunakan Element <div>

function App() {

	return (
		<div>
			<p> Belajar React </p>
			<p> di SantriKoding.com </p>
		</div>
	)

}

Di atas tidak akan mengahasilkan error, karena kedua element tersebut dibungkus menggunakan element <div>.

Menggunakan React.Fragment

Kita juga bisa menggunakan React.Fragment untuk membungkus banyak element di dalam return-value. Contohnya seperti berikut ini :

function App() {

	return (
		<React.Fragment>
			<p> Belajar React </p>
			<p> di SantriKoding.com </p>
		</React.Fragment>
	)

}

Menggunakan Array dan Empty Tag

Dan berikut ini contoh menampilkan banyak element menggunakan array dan empty tag di dalam JSX.

function App() {

	return [
			<p> Belajar React </p>
			<p> di SantriKoding.com </p>
		]
	)

}
function App() {

	return (
			<>
				<p> Belajar React </p>
				<p> di SantriKoding.com </p>
			</>
		)
	)

}

Penulisan Attribute Class HTML di JSX

Di dalam JSX kita tidak disarankan menggunakan attribute yang bernama class, karena nama tersebut merupakan keyword yang ada di dalam JavaScript. Sebagai gantinya kita disarankan menggunakan nama className. Contohnya seperti berikut ini :

Penulisan attribute class yang salah di dalam JSX

function App() {

	return (
		<div class="app">
			<p> Belajar React </p>
			<p> di SantriKoding.com </p>
		</div>
	)

}

Penulisan attribute class yang benar di dalam JSX

function App() {

	return (
		<div className="app">
			<p> Belajar React </p>
			<p> di SantriKoding.com </p>
		</div>
	)

}

Dari kedua kode di atas, perbedaanya ada pada penulisan attribute class dan className. Kalau di JSX kita harus mengganti semua attribute yang bernama class menjadi className.

Inline Style di dalam JSX

Di dalam JSX untuk membuat inline style menggunakan CSS harus berupa object dan nama attribute dari CSS-nya menjadi camelCase. Contohnya kurang lebih seperti berikut ini :

function App() {

	return (
		<div className="app">
			<p style={{ backgroundColor: 'red' }}> Belajar React </p>
			<p style={{ fontSize: 14 }}> di SantriKoding.com </p>
		</div>
	)

}

Tanda kurung kurawal {...} berarti teks di dalamnya adalah kode JavaScript, bukan teks biasa.

Penulisan Event Handler di JSX

Di dalam HTML, kita biasanya menuliskan beberapa event handler seperti berikut ini : onclick, onfocus dan lain-lain.

Nah di dalam JSX untuk menuliskan event handler tersebut kita ubah menjadi camelCase. Kurang lebih seperti berikut ini : onClick, onFocus dan lain-lain.

function App() {

	const = handleClick = () => alert('CLICKED!');
	
	return (
		<div className="app">
			<button onClick={handleClick}> My Button </button>
		</div>
	)
}

Kondisional di dalam JSX

JSX sangat mendukung apa yang disebut dengan kondisional rendering, yaitu membuat sebuah logika untuk menampilkan element atau komponen berdasarkan kondisi tertentu. Contohnya seperti berikut ini :

function App() {

	const showButton = false;
	
	return (
	
		<div>
		
			{/* Tampilkan button kalo showButton = true */}
			{showButton && <button>Click Me</button>}
			
			{/* Tampilkan teks ini kalo showButton = false */}
			{!showButton && <p>No button</p>}
			
		</div>
	
	)

}

Dari logika kondisi di atas bisa juga dipersingkat menggunakan ternary operator. Kurang lebih seperti berikut ini :

function App() {

	const showButton = false;
	
	return (
	
		<div>
		
			{
				showButton ? <button>Click Me</button> : <p>No button</p>
			}
			
		</div>
	
	)

}

Lifecycle dan Hooks di React.js


Berbicara tentang React, hal pertama yang menjadikan library ini sangat disukai adalah kemampuan melakukan update sebuah tampilan dan data secara otomatis jika terdapat perubahan. Kemampuan tersebut di dalam React disebut dengan lifecycle atau kalau diterjemahkan adalah siklus hidup.

React Lifecycle - Class Component

Pertama. kita akan membahas tentang lifecycle atau siklus hidup yang ada di dalam React. Sama seperti kita (manusia), di React ada 3 fase siklus hidup. Yaitu :

  1. dimana kita dilahirkan (mounting)
  2. kemudian berkembang (updating)
  3. dan kematian (unmounting).

Mounting

Fase ini mengacu pada pembuatan komponen. Di sinilah komponen ditambahkan ke DOM. Berikut ini adalah beberapa lifecycle yang tersedia untuk fase ini:

1. constructor()

Sebelum memulai fase mounting, kita mungkin perlu menginisialisasi komponen menggunakan method constructor(). Ini digunakan ketika kita perlu menginisialisasi sebuah state dan set method ke dalam komponen. Ini adalah satu-satunya tempat di mana this.state ditetapkan secara eksplisit.

2. static getDerivedStateFromProps()

Setelah inisialisasi, fungsi berikutnya yang dipanggil adalah static getDerivedStateFromProps(). Method ini dipanggil sebelum komponen di render (dan sebelum dipasang).

Method ini memungkinkan komponen untuk memperbarui state berdasarkan perubahan pada props. Ini jarang digunakan dan harus digunakan dengan hati-hati karena dapat menyebabkan kesalahan. Aturan umum sebagai pemula, mungkin kita tidak membutuhkannya dan harus menghindari menggunakannya.

3. render()

Method render() adalah satu-satunya method yang harus dimiliki komponen. Itu akan selalu dipanggil dan tugasnya adalah memasang komponen ke DOM.

4. componentDidMount()

Fungsi terakhir dalam fase ini adalah componentDidMount(). Method ini akan segera dipanggil setelah fungsi render dijalankan. Jika kita perlu berinteraksi dengan browser secara langsung, di sinilah kita melakukannya.

Disini kita bisa melakukan HTTP request ke Rest API dan memperbarui state pada component berdasarkan response yang di dapatkan dari Rest API.


Updating

Fase kedua ini mewakili waktu di mana komponen perlu diperbarui karena terjadi perubahan pada props atau state. Perubahan ini dapat terjadi di dalam komponen atau melalui backend. Perubahan ini akan memanggil fungsi render() lagi.

Berikut ini adalah beberapa lifecycle yang tersedia untuk fase ini:

1. static getDeprivedStateFromProps()

Ini adalah method pertama yang dipanggil dalam fase ini. Method ini adalah method yang sama yang digunakan dalam fase mounting.

2. shouldComponentUpdate()

Method selanjutnya yang akan dipanggil adalah method shouldComponentUpdate(). Seperti namanya, method ini memberi kita kendali atas apakah suatu komponen harus diperbarui atau tidak karena perubahan pada properti atau state-nya. Secara default, komponen akan selalu dirender ulang saat diperbarui. Method ini dapat mengembalikan nilai true atau false.

3. render()

Jika shouldComponentUpdate() mengembalikan nilai true, maka fungsi render akan dipanggil.

4. getSnapshotBeforeUpdate()

Dalam method ini, kita diberikan akses ke props dan nilai state sebelum pembaruan dilakukan ke DOM. Meskipun fungsi render sudah dipanggil, kita masih bisa melihat nilai sebelumnya.

5. componentDidUpdate()

Method ini adalah yang terakhir dipanggil dalam fase ini. Seperti method sebelumnya, method ini juga menerima props sebelumnya dan nilai state sebagai argumen tetapi juga menerima nilai kembalian getSnapshotBeforeUpdate() sebagai argumen ketiga (jika ada).


Unmounting

Fase unmount adalah di mana komponen dihapus dari DOM. Ini menandai akhir dari siklus hidup komponen. Dalam fase ini, kita memiliki satu method yang tersedia, yaitu :

componentWillUnmount()

Method ini dijalankan tepat sebelum komponen dilepas dari DOM. Disini kita bisa membersihkan semua yang perlu dihapus sebelum komponen dihilangkan.

React Hooks - Function Component

Dan sejak React versi 16.81 diperkenalkan fitur baru yang bernama Hooks, dimana fitur ini memungkinkan kita menggunakan fitur-fitur yang ada di React tanpa menggunakan Class Component.

Hooks merupakan fungsi yang memungkinkan kita untuk “mengaitkan” state dan fitur-fitur lifecycle React di function component. Hooks tidak dapat berfungsi didalam Class Component.

Hooks akan kita pakai di dalam studi kasus ini, karena lebih simple dan mudah dibandingkan menggunakan Class Component. Di dalam studi kasus ini, kita akan sering menggunakan 2 hook yaitu : useState dan useEffect.

Berikut ini perbedaan antara Lifecycle dan Hooks yang ada di dalam React.

Lifecycle (Class Component) Hooks (Function Component)
Dikelanlkan sejak React versi awal. Dikenalkan sejak React versi 16.8 di tahun 2018.
Bekerja dengan JavaScript ES5. Bekerja dengan JavaScript ES6 dan yang lebih baru.
Berbasis Class Component. Berbasis Function Component.
Membutuhkan constructor untuk inisialisasi. Tidak membutuhkan constructor.
Membutuhkan keyword this untuk update state Tidak membutuhkan keyword this untuk update state.

useState

useState di panggil dalam function component untuk menambahkan suatu state lokal. React akan menyimpan state antar render. useState memberikan dua hal: nilai state saat ini dan fungsi untuk memperbarui nilai tersebut.

//define a state
const [count, setCount] = useState(0);

Di atas, count merupakan state yang digunakan untuk menyimpan nilai-nya. Sedangkan setCount adalah method yang digunakan untuk memperbaru nilai dari state tersebut. Dan untuk useState(0) adalah nilai default yang kita berikan pada state tersebut.

Berikut ini contoh menggunakan useState untuk melakukan perhitungan.

//import hook "useState" dari React
import React, { useState } from 'react';

function Example() {

  // Deklarasi sebuah variabel state baru, dimana akan dinamakan "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      {/* cetak state "count" */}
      <p>Anda klik sebanyak {count} kali</p>
      
      {/* handle button click */}
      <button onClick={() => setCount(count + 1)}>
        Klik saya
      </button>
      
    </div>
  );
}

Di atas, saat button di klik maka akan menjalankan handler dari state yaitu setCount. Dimana berisi nilai state yang ada dan ditambahkan angka 1.

setCount(count + 1)

useEffect

Kita tentunya pernah melakukan pengambilan data, berlangganan data (subscription), atau secara manual mengubah DOM dari komponen React sebelumnya. Teknik seperti ini dinamakan dengan “efek samping (side effects)” (atau singkatnya “efek (effects)”) karena dapat mempengaruhi komponen lain dan tidak dapat dilakukan pada saat proses render.

Effect Hook, useEffect, menambahkan kemampuan untuk melakukan “efek samping” dari sebuah function component. Hook ini memiliki fungsi yang sama dengan componentDidMount, componentDidUpdate, dan componentWillUnmount yang ada pada Class Component React, tetapi disatukan menjadi satu API.

Sebagai contoh, komponen berikut menetapkan judul halaman setelah React memperbarui DOM:

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Di atas, pada hook useEffect akan selalu dijalankan ketika ada perubahan baik tampilan atau data di dalam komponen.

Jika button di klik akan melakukan update nilai state count dan di dalam hook useEffect melakukan set judul halaman dengan data state yang telah diperbarui.


Hook useEffect biasa kita gunakan untuk menjalankan kode pada waktu :

  1. Komponen ditampilkan pertama kali (mounted).
  2. Ada sebuah perubahan yang terjadi pada State atau Props.
useEffect(()=>{
	// kode dijalankan waktu komponen pertama kali ditampilkan
},[])
useEffect(()=>{
	// kode dijalanin waktu mystate atau myprop berubah
},[mystate, myprop])
Í
Beranda Mundur Maju