Akses kelas selamanya

Ambil Promo
flash sale
hamburger-menu

Tips All

Meningkatkan skills menjadi 1% lebih baik

Reset
Kelas Apa itu Filament PHP pada Laravel dan Mengapa Web Developer Wajib Pake di BuildWithAngga

Apa itu Filament PHP pada Laravel dan Mengapa Web Developer Wajib Pake

Filament adalah paket admin panel yang dibangun khusus untuk Laravel dan dirancang agar developer dapat membuat dashboard dan halaman admin dengan cepat, mudah, dan fungsional. Filament menyediakan berbagai komponen antarmuka yang siap pakai, seperti form, tabel, dan fitur CRUD, yang secara signifikan mempercepat pengembangan halaman admin dalam proyek Laravel. Mengapa developer perlu belajar menggunakan Filament pada proyek Laravel? Pertama, Filament dirancang untuk mengikuti gaya dan ekosistem Laravel, sehingga sangat cocok bagi developer yang sudah terbiasa dengan framework tersebut. Kedua, Filament memungkinkan developer untuk membuat dashboard dan manajemen data dengan sedikit kode namun tetap fleksibel, sehingga meminimalkan waktu pengembangan. Ketiga, Filament menyediakan komponen-komponen canggih, seperti Wizard dan Relational Manager, yang mempermudah developer dalam menangani data yang kompleks. Bagi developer yang ingin meningkatkan produktivitas dan mempermudah manajemen aplikasi skala besar, Filament menjadi solusi tepat. Selain itu, komunitas Filament terus berkembang, menyediakan banyak dukungan dan dokumentasi yang membantu pemula dan profesional agar bisa memanfaatkan semua fitur dengan maksimal.

Kelas Cara Bikin Dashboard Steps dengan Filament Wizard dan Laravel di BuildWithAngga

Cara Bikin Dashboard Steps dengan Filament Wizard dan Laravel

Membuat dashboard admin yang menarik adalah langkah penting dalam menciptakan pengalaman pengguna yang baik dalam menggunakan website. Dashboard yang dirancang dengan baik akan memudahkan pengguna untuk berinteraksi, memahami data, dan mengelola konten di dalam aplikasi. Tidak hanya estetika, dashboard yang user-friendly juga memberikan navigasi yang jelas, fitur yang terorganisir, dan tata letak yang intuitif. Pengalaman pengguna yang positif dalam mengakses dashboard dapat meningkatkan kepercayaan dan kepuasan terhadap aplikasi, serta memperkuat loyalitas pengguna. Laravel dan Filament: Kombinasi Tepat untuk Dashboard Laravel adalah salah satu framework web development yang populer di kalangan developer karena performa, fleksibilitas, dan kemudahan penggunaannya. Laravel memungkinkan developer membangun aplikasi web dengan struktur yang rapi dan teratur, serta mendukung berbagai fitur untuk mempermudah proses development. Filament adalah library berbasis Laravel yang dirancang khusus untuk membuat dashboard dan halaman admin secara cepat dan efisien. Dengan Filament, proses membuat dashboard menjadi jauh lebih mudah karena library ini menyediakan komponen-komponen antarmuka yang siap pakai dan dapat dikustomisasi. Bagi para developer, Filament adalah solusi tepat untuk menghemat waktu tanpa harus memulai dari awal, sementara tetap mempertahankan kualitas tampilan dan performa aplikasi. Kelebihan Filament Wizard dalam Dashboard Steps Salah satu fitur menarik dari Filament adalah Wizard. Filament Wizard memungkinkan developer untuk membuat form dengan alur bertahap atau langkah-langkah yang terstruktur. Fitur ini sangat berguna ketika ingin mengelola input data yang kompleks namun mudah dipahami oleh pengguna. Wizard ini juga memberikan visualisasi proses yang tersegmentasi, sehingga pengguna dapat mengikuti proses dengan lebih mudah. Dengan menggunakan Wizard dari Filament, developer dapat membangun dashboard steps yang memandu pengguna melalui beberapa tahapan input data dengan alur yang jelas dan interaktif. Membuat Proyek Website Home Service dengan Laravel dan Composer Pertama, pastikan Composer telah terinstal di komputer Anda. Composer adalah manajer dependency PHP yang akan membantu menginstal Laravel dan semua dependensinya. Buka terminal dan buat proyek Laravel baru dengan menggunakan perintah berikut: composer create-project --prefer-dist laravel/laravel home-service Setelah proses instalasi selesai, masuk ke direktori proyek baru tersebut: cd home-service Selanjutnya, pastikan Laravel berjalan dengan benar. Jalankan server development Laravel dengan perintah: php artisan serve Akses aplikasi di browser dengan membuka URL http://localhost:8000. Jika muncul halaman welcome dari Laravel, proyek Anda telah berhasil dibuat. Mengatur File .env untuk Database MySQL pada Proyek Laravel Untuk menghubungkan proyek Laravel dengan MySQL, buka file .env di root proyek Anda. Cari bagian konfigurasi database, dan sesuaikan nilai-nilai berikut: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database DB_USERNAME=username_mysql DB_PASSWORD=password_mysql Pastikan nilai DB_DATABASE, DB_USERNAME, dan DB_PASSWORD sesuai dengan database yang Anda buat di MySQL. Misalnya, jika Anda memiliki database bernama home_service_db, konfigurasi .env akan terlihat seperti ini: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=home_service_db DB_USERNAME=root DB_PASSWORD=12345 Setelah selesai mengatur konfigurasi, jalankan migrasi untuk memastikan Laravel terhubung dengan database dan membuat tabel sesuai dengan file migrasi: php artisan migrate Jika berhasil, maka tabel akan dibuat di database, dan proyek Laravel Anda siap menggunakan MySQL sebagai basis datanya. Membuat File Model dan Migration untuk Table Category, Home Services, dan Booking Transaction Untuk membuat tabel di Laravel, kita perlu membuat file model dan migration. Berikut adalah langkah-langkahnya untuk tabel Category, HomeService, dan BookingTransaction. Membuat Model dan Migration untuk Tabel Category Buka terminal di direktori proyek Laravel Anda. Buat model dan migration untuk tabel Category dengan perintah: php artisan make:model Category -m Perintah di atas akan membuat model Category dan file migration di database/migrations. Selanjutnya, buka file migration yang baru dibuat (biasanya memiliki nama yang mirip dengan xxxx_xx_xx_xxxxxx_create_categories_table.php). Di dalam file migration Category, tambahkan kolom-kolom yang diperlukan. Misalnya: Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('description')->nullable(); $table->timestamps(); }); Simpan file ini, kemudian jalankan perintah migrasi untuk membuat tabel categories: php artisan migrate Membuat Model dan Migration untuk Tabel HomeService Selanjutnya, buat model dan migration untuk tabel HomeService dengan perintah berikut: php artisan make:model HomeService -m Buka file migration untuk HomeService di folder database/migrations. Tambahkan kolom-kolom yang diperlukan. Contoh kode untuk struktur tabel HomeService: Schema::create('home_services', function (Blueprint $table) { $table->id(); $table->foreignId('category_id')->constrained('categories')->onDelete('cascade'); $table->string('service_name'); $table->text('service_description')->nullable(); $table->decimal('price', 8, 2); $table->timestamps(); }); Di sini, category_id akan menjadi foreign key yang menghubungkan setiap layanan dengan kategori tertentu. Pastikan category_id dihubungkan ke tabel categories dan diberi fitur cascading delete. Setelah selesai, jalankan perintah migrasi: php artisan migrate Membuat Model dan Migration untuk Tabel BookingTransaction Buat model dan migration untuk tabel BookingTransaction dengan perintah berikut: php artisan make:model BookingTransaction -m Buka file migration untuk BookingTransaction yang baru saja dibuat. Tambahkan kolom-kolom sesuai dengan kebutuhan aplikasi. Contoh kode untuk struktur tabel BookingTransaction: Schema::create('booking_transactions', function (Blueprint $table) { $table->id(); $table->foreignId('home_service_id')->constrained('home_services')->onDelete('cascade'); $table->string('customer_name'); $table->string('customer_phone'); $table->date('booking_date'); $table->string('status')->default('pending'); $table->timestamps(); }); Dalam tabel ini, home_service_id adalah foreign key yang menghubungkan setiap transaksi dengan layanan tertentu. Kolom status dapat digunakan untuk mencatat status pemesanan, misalnya pending, confirmed, atau completed. Jalankan migrasi setelah menyimpan file: php artisan migrate Cara Mengatur File Model untuk Fillable dan Relationship pada Model Category, HomeService, dan BookingTransaction Pada langkah ini, kita akan menambahkan atribut fillable pada setiap model agar kolom-kolomnya dapat diisi massal (mass assignment) serta mengatur relasi antar model. Berikut penjelasannya untuk masing-masing model. Mengatur Model Category Buka file Category.php di dalam folder app/Models. Tambahkan properti fillable untuk kolom-kolom yang bisa diisi dan atur relasi dengan model HomeService. Berikut contoh kode lengkapnya: namespace App\\\\Models; use Illuminate\\\\Database\\\\Eloquent\\\\Factories\\\\HasFactory; use Illuminate\\\\Database\\\\Eloquent\\\\Model; class Category extends Model { use HasFactory; protected $fillable = ['name', 'description']; public function homeServices() { return $this->hasMany(HomeService::class); } } Pada model Category: Properti fillable memungkinkan kolom name dan description untuk diisi secara massal.Method homeServices() mendefinisikan relasi hasMany dengan model HomeService, yang artinya satu kategori dapat memiliki banyak layanan. Mengatur Model HomeService Buka file HomeService.php di dalam folder app/Models. Tambahkan properti fillable untuk kolom-kolom yang bisa diisi dan atur relasi dengan model Category serta BookingTransaction. Berikut contoh kode lengkapnya: namespace App\\\\Models; use Illuminate\\\\Database\\\\Eloquent\\\\Factories\\\\HasFactory; use Illuminate\\\\Database\\\\Eloquent\\\\Model; class HomeService extends Model { use HasFactory; protected $fillable = ['category_id', 'service_name', 'service_description', 'price']; public function category() { return $this->belongsTo(Category::class); } public function bookingTransactions() { return $this->hasMany(BookingTransaction::class); } } Pada model HomeService: Properti fillable memungkinkan kolom category_id, service_name, service_description, dan price untuk diisi secara massal.Method category() mendefinisikan relasi belongsTo dengan model Category, yang menunjukkan bahwa setiap layanan home service terkait dengan satu kategori.Method bookingTransactions() mendefinisikan relasi hasMany dengan model BookingTransaction, yang artinya satu layanan dapat memiliki banyak transaksi booking. Mengatur Model BookingTransaction Buka file BookingTransaction.php di dalam folder app/Models. Tambahkan properti fillable untuk kolom-kolom yang bisa diisi dan atur relasi dengan model HomeService. Berikut contoh kode lengkapnya: namespace App\\\\Models; use Illuminate\\\\Database\\\\Eloquent\\\\Factories\\\\HasFactory; use Illuminate\\\\Database\\\\Eloquent\\\\Model; class BookingTransaction extends Model { use HasFactory; protected $fillable = ['home_service_id', 'customer_name', 'customer_phone', 'booking_date', 'status']; public function homeService() { return $this->belongsTo(HomeService::class); } } Pada model BookingTransaction: Properti fillable memungkinkan kolom home_service_id, customer_name, customer_phone, booking_date, dan status untuk diisi secara massal.Method homeService() mendefinisikan relasi belongsTo dengan model HomeService, yang menunjukkan bahwa setiap transaksi booking terkait dengan satu layanan home service. Ringkasan Relasi Antar Model Category memiliki relasi hasMany ke HomeService.HomeService memiliki relasi belongsTo ke Category dan hasMany ke BookingTransaction.BookingTransaction memiliki relasi belongsTo ke HomeService. Dengan demikian, relasi antar model telah diatur, dan kolom-kolom yang diperlukan telah ditambahkan ke properti fillable. Cara Menginstall Package Filament 3 dan Membuat Akun Super Admin Langkah 1: Menginstall Package Filament 3 Pastikan proyek Laravel Anda sudah siap. Buka terminal di direktori proyek Laravel Anda, lalu install Filament versi 3 menggunakan Composer: composer require filament/filament:"^3.0" Perintah ini akan menginstal Filament versi 3 dan semua dependensinya pada proyek Laravel Anda. Langkah 2: Memasang Filament dan Menyiapkan Konfigurasi Setelah instalasi selesai, jalankan perintah berikut untuk mempublikasi aset dan konfigurasi default dari Filament: php artisan vendor:publish --tag=filament-config File konfigurasi ini berada di config/filament.php dan dapat Anda sesuaikan dengan kebutuhan proyek, seperti pengaturan URL dashboard, middleware, dan tema. Langkah 3: Membuat Akun Super Admin dengan Perintah php artisan make:filament-user Untuk mengakses dashboard Filament, Anda perlu membuat akun super admin yang memiliki akses penuh. Filament menyediakan perintah Artisan untuk membuat pengguna ini dengan cepat. Jalankan perintah berikut di terminal: php artisan make:filament-user Perintah ini akan meminta Anda mengisi informasi akun untuk super admin. Masukkan data yang diminta sebagai berikut: Name: Masukkan nama untuk akun super admin, misalnya "Super Admin".Email: Masukkan email yang akan digunakan untuk login ke dashboard Filament, misalnya "[email protected]".Password: Masukkan password yang aman untuk akun super admin.Is Super Admin: Ketik yes untuk memberikan hak akses super admin. Contoh input: Name: Super Admin Email: [email protected] Password: password123 Is Super Admin (yes/no): yes Setelah Anda mengisi semua data, akun super admin akan dibuat. Anda bisa menggunakannya untuk login ke dashboard Filament. Langkah 4: Mengakses Dashboard Filament Setelah akun super admin berhasil dibuat, Anda dapat mengakses dashboard Filament melalui URL default http://localhost/admin. Gunakan email dan password yang telah Anda buat untuk masuk. Akun super admin kini memiliki akses penuh untuk mengelola semua fitur yang ada di dashboard Filament. Cara Membuat Resource untuk CRUD Data Category, Home Service, dan Booking Transaction Menggunakan Filament Filament menyediakan command yang mempermudah pembuatan resource CRUD secara otomatis. Berikut adalah langkah-langkahnya untuk membuat resource CRUD pada data Category, HomeService, dan BookingTransaction. Langkah 1: Membuat Resource CRUD untuk Data Category Buka terminal di direktori proyek Laravel Anda. Buat resource CRUD untuk data Category menggunakan perintah berikut: php artisan make:filament-resource Category Filament akan membuat file resource di dalam folder app/Filament/Resources/CategoryResource.php. Buka file tersebut untuk melihat pengaturan CRUD yang telah dihasilkan otomatis oleh Filament. Di dalam CategoryResource.php, Anda dapat menyesuaikan form dan tabel untuk CRUD data Category. Berikut contoh penyesuaian di dalam method form dan table: public static function form(Form $form): Form { return $form ->schema([ TextInput::make('name') ->required() ->label('Category Name'), Textarea::make('description') ->label('Description') ->nullable(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name')->label('Category Name'), TextColumn::make('description')->label('Description'), TextColumn::make('created_at')->dateTime(), ]) ->filters([ // ]); } Langkah 2: Membuat Resource CRUD untuk Data Home Service Lanjutkan dengan membuat resource untuk HomeService menggunakan perintah berikut di terminal: php artisan make:filament-resource HomeService Filament akan membuat resource baru di app/Filament/Resources/HomeServiceResource.php. Buka file ini untuk mengonfigurasi form dan tabel CRUD untuk HomeService. Berikut adalah contoh pengaturan method form dan table di dalam file HomeServiceResource.php: public static function form(Form $form): Form { return $form ->schema([ Select::make('category_id') ->relationship('category', 'name') ->required() ->label('Category'), TextInput::make('service_name') ->required() ->label('Service Name'), Textarea::make('service_description') ->label('Service Description') ->nullable(), TextInput::make('price') ->numeric() ->required() ->label('Price'), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('category.name')->label('Category'), TextColumn::make('service_name')->label('Service Name'), TextColumn::make('price')->label('Price')->money('USD', true), TextColumn::make('created_at')->dateTime(), ]) ->filters([ // ]); } Cara Membuat Resource untuk Booking Transaction dan Menggunakan Component Wizard di Filament Filament menyediakan cara mudah untuk membuat resource CRUD dengan tampilan bertahap (wizard) agar data yang kompleks bisa diinput dalam beberapa langkah. Berikut adalah panduan langkah demi langkah untuk membuat resource CRUD pada BookingTransaction dengan komponen Wizard untuk input data baru. Langkah 1: Membuat Resource BookingTransaction Buka terminal di direktori proyek Laravel Anda. Buat resource untuk BookingTransaction dengan perintah berikut: php artisan make:filament-resource BookingTransaction Filament akan menghasilkan file resource baru bernama BookingTransactionResource.php di dalam folder app/Filament/Resources. Buka file tersebut untuk mengatur form dengan komponen Wizard. Langkah 2: Menggunakan Component Wizard untuk Input Data Baru Pada file BookingTransactionResource.php, kita akan memodifikasi method form agar menggunakan komponen Wizard. Wizard ini akan membagi proses input data BookingTransaction menjadi beberapa langkah yang terstruktur. Contoh kode untuk membuat form Wizard: use Filament\\\\Forms\\\\Components\\\\Wizard; use Filament\\\\Forms\\\\Components\\\\Wizard\\\\Step; use Filament\\\\Forms\\\\Components\\\\TextInput; use Filament\\\\Forms\\\\Components\\\\DatePicker; use Filament\\\\Forms\\\\Components\\\\Select; public static function form(Form $form): Form { return $form ->schema([ Wizard::make([ Step::make('Customer Information') ->schema([ TextInput::make('customer_name') ->required() ->label('Customer Name'), TextInput::make('customer_phone') ->required() ->label('Customer Phone'), ]), Step::make('Service Selection') ->schema([ Select::make('home_service_id') ->relationship('homeService', 'service_name') ->required() ->label('Select Home Service'), DatePicker::make('booking_date') ->required() ->label('Booking Date'), ]), Step::make('Booking Status') ->schema([ Select::make('status') ->options([ 'pending' => 'Pending', 'confirmed' => 'Confirmed', 'completed' => 'Completed', ]) ->default('pending') ->required() ->label('Status'), ]), ]) ]); } Pada kode di atas: Wizard::make([]) digunakan untuk membungkus form dalam format bertahap (wizard).Step::make('Customer Information') membuat langkah pertama, di mana informasi pelanggan seperti customer_name dan customer_phone diinput.Step::make('Service Selection') membuat langkah kedua, di mana pengguna memilih layanan home service dan tanggal booking.Step::make('Booking Status') membuat langkah ketiga, di mana pengguna memilih status pemesanan (status). Dengan cara ini, proses input data untuk BookingTransaction dibagi menjadi beberapa tahap, sehingga lebih mudah dipahami dan diikuti oleh pengguna. Langkah 3: Mengakses dan Menguji Form Wizard di Dashboard Filament Setelah form wizard untuk BookingTransaction diatur, jalankan server Laravel: php artisan serve Kemudian buka URL http://localhost/admin di browser dan login dengan akun admin. Cari menu BookingTransaction dan coba tambahkan data baru. Anda akan melihat form bertahap yang dibuat menggunakan komponen Wizard, yang memandu pengguna dalam mengisi data BookingTransaction selangkah demi selangkah. Dengan Wizard ini, input data yang kompleks dapat diatur dengan rapi, sehingga meningkatkan pengalaman pengguna dalam menggunakan dashboard Filament. Penutup Membangun fitur CRUD dan mengelola data dengan komponen seperti Filament Wizard sangat membantu dalam menciptakan aplikasi yang interaktif dan mudah digunakan. Dengan menggunakan Laravel dan Filament, programmer dapat membuat dashboard yang rapi, efisien, dan mendukung pengalaman pengguna yang lebih baik. Namun, untuk benar-benar menguasai teknik-teknik seperti ini, belajar bersama mentor yang berpengalaman sangat direkomendasikan. Di BuildWithAngga, Anda bisa belajar bersama para expert yang siap membantu Anda memahami konsep-konsep penting dalam web development. Dengan mengikuti kelas di BuildWithAngga, Anda akan mendapatkan akses selamanya ke materi kursus, konsultasi langsung dengan mentor, serta kesempatan membangun portfolio menarik yang dapat meningkatkan peluang Anda dalam dunia kerja. Jadi, jangan ragu untuk bergabung dan memperdalam kemampuan programming Anda di BuildWithAngga!

Kelas Tutorial Fitur Role Management dengan Laravel 11, Filament 3, dan Spatie 6 Projek Toko Buah di BuildWithAngga

Tutorial Fitur Role Management dengan Laravel 11, Filament 3, dan Spatie 6 Projek Toko Buah

Dalam era digital saat ini, perusahaan dituntut untuk memiliki website yang modern dan kaya fitur, terutama bagi mereka yang menjual jasa atau produk. Website bukan hanya menjadi etalase digital, tetapi juga memberikan nilai lebih kepada pengguna dengan menghadirkan fitur-fitur yang meningkatkan pengalaman mereka. Misalnya, pengguna ingin merasakan kenyamanan saat melakukan transaksi, berinteraksi dengan konten, hingga mendapatkan layanan yang dipersonalisasi berdasarkan kebutuhan mereka. Di sinilah pentingnya sebuah sistem manajemen peran (role management) yang terstruktur dengan baik. Dengan sistem manajemen peran, perusahaan dapat memberikan hak akses yang berbeda kepada pengguna berdasarkan perannya. Misalnya, admin memiliki akses penuh untuk mengelola produk, transaksi, dan pengguna, sementara pelanggan hanya bisa melihat dan membeli produk. Manajemen peran ini memberikan keamanan lebih pada sistem, memastikan bahwa hanya pihak yang berwenang yang dapat melakukan tindakan tertentu. Laravel menjadi pilihan framework yang tepat untuk membangun website modern semacam ini. Dengan fitur-fitur yang lengkap dan komunitas developer yang besar, Laravel mempermudah proses development. Selain itu, Laravel juga dikenal sebagai framework yang aman, cepat, dan scalable, sehingga cocok untuk membangun website dengan berbagai fitur kompleks. Ditambah dengan integrasi dengan Filament 3 sebagai admin panel yang kuat, dan Spatie 6 sebagai package untuk manajemen peran dan izin, proses development menjadi lebih cepat dan terorganisir. Filament 3: Solusi Cepat untuk Membangun Dashboard Admin Dalam proses pembuatan website modern, pengelolaan konten dan data di belakang layar menjadi sangat penting, terutama bagi admin yang perlu mengelola produk, transaksi, atau pengguna. Untuk itu, dibutuhkan sebuah dashboard admin yang mudah digunakan dan fungsional. Filament 3 hadir sebagai solusi cepat bagi developer yang ingin membangun dashboard admin dengan lebih efisien. Package ini dirancang khusus untuk Laravel dan memudahkan proses pembuatan dashboard yang interaktif, lengkap dengan berbagai fitur seperti pengelolaan data, tabel, dan form yang dapat diintegrasikan dengan mudah. Dengan menggunakan Filament 3, developer tidak perlu memulai semuanya dari nol. Fitur-fitur seperti tabel yang sudah dioptimalkan, integrasi form, hingga manajemen data bisa dibangun dengan cepat. Ini sangat membantu perusahaan yang membutuhkan dashboard admin yang user-friendly untuk mempermudah pekerjaan tim internal mereka. Filament 3 juga memiliki fleksibilitas untuk disesuaikan dengan kebutuhan spesifik proyek, sehingga mempermudah developer dalam menambahkan fitur tambahan sesuai kebutuhan klien. Spatie Laravel Permission: Package Populer untuk User Roles Spatie Laravel Permission merupakan salah satu package terpopuler di ekosistem Laravel untuk membangun fitur manajemen peran dan izin (user roles and permissions) pada sebuah website modern. Di dunia web development, fitur ini menjadi sangat penting untuk memastikan bahwa setiap pengguna mendapatkan hak akses yang sesuai dengan perannya. Misalnya, dalam sebuah sistem e-commerce, ada peran seperti admin, pelanggan, atau manajer toko, di mana masing-masing memiliki tingkat akses yang berbeda. Spatie menyediakan berbagai fitur untuk memudahkan developer dalam mengelola peran dan izin ini, tanpa harus membangun semuanya dari awal. Dengan integrasi yang mulus ke dalam Laravel, Spatie Laravel Permission memungkinkan developer untuk mengatur siapa saja yang bisa mengakses halaman tertentu, mengelola produk, atau melakukan transaksi. Paket ini sangat fleksibel dan mudah digunakan, serta dapat diandalkan untuk membangun website yang aman dan terstruktur dengan baik. Membangun Fitur Role Management pada Website Toko Buah Online Pada artikel ini, kita akan belajar bagaimana membuat fitur role management untuk sebuah website toko buah online. Dalam proyek ini, kita akan menggunakan kombinasi Laravel 11, Filament 3, dan Spatie Laravel Permission untuk mengelola peran pengguna. Website ini akan memiliki beberapa role, seperti: Admin: memiliki akses penuh untuk mengelola semua aspek di dalam website, termasuk menambah atau menghapus produk, melihat laporan penjualan, dan mengelola pengguna.Merchant: peran ini diberikan kepada penjual buah yang dapat menambah, mengedit, dan menghapus produk mereka sendiri, serta memantau pesanan yang masuk dari pelanggan.Customer: pengguna biasa yang hanya memiliki akses untuk menjelajah produk, melakukan pembelian, dan melihat status pesanan mereka. Dengan sistem role management ini, kita dapat memastikan bahwa setiap pengguna hanya bisa mengakses fitur-fitur yang sesuai dengan hak dan tanggung jawab mereka. Hal ini penting untuk menjaga keamanan, efisiensi, dan pengalaman pengguna yang optimal pada website. Membuat Proyek Toko Buah dengan Laravel Berikut adalah panduan lengkap untuk membuat proyek toko buah menggunakan Laravel melalui terminal, mengatur koneksi database MySQL, serta membuat migration dan model untuk tabel products, categories, dan transactions. Install Laravel Melalui Composer Langkah pertama adalah menginstall Laravel. Buka terminal dan jalankan perintah berikut untuk membuat proyek Laravel baru: composer create-project --prefer-dist laravel/laravel toko-buah Setelah instalasi selesai, masuk ke direktori proyek: cd toko-buah Mengatur File .env untuk Koneksi Database MySQL Setelah proyek Laravel berhasil dibuat, buka file .env yang ada di root folder proyek. Ubah konfigurasi database agar sesuai dengan setup MySQL di komputer lokal: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database DB_USERNAME=root DB_PASSWORD= Gantilah nama_database dengan nama database yang kamu buat di MySQL. Pastikan MySQL sudah aktif dan database yang dimaksud sudah tersedia. Membuat Migration dan Model untuk Produk (Product) Langkah selanjutnya adalah membuat migration dan model untuk tabel produk. Jalankan perintah berikut di terminal: php artisan make:model Product -m Perintah di atas akan membuat model Product beserta file migration-nya. Buka file migration yang ada di database/migrations, lalu modifikasi fungsi up untuk menambahkan struktur tabel products: public function up() { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->decimal('price', 8, 2); $table->integer('stock'); $table->unsignedBigInteger('category_id'); $table->timestamps(); $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade'); }); } Tabel products akan memiliki kolom name, price, stock, serta relasi category_id yang terhubung ke tabel categories. Membuat Migration dan Model untuk Kategori (Category) Buat model dan migration untuk tabel kategori menggunakan perintah berikut: php artisan make:model Category -m Setelah itu, buka file migration yang dihasilkan dan sesuaikan dengan struktur berikut: public function up() { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps(); }); } Tabel categories ini akan digunakan untuk mengelompokkan produk berdasarkan kategori buah. Membuat Migration dan Model untuk Transaksi (Transactions) Selanjutnya, buat model dan migration untuk tabel transaksi dengan perintah ini: php artisan make:model Transaction -m Kemudian, modifikasi file migration untuk tabel transactions seperti berikut: public function up() { Schema::create('transactions', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('product_id'); $table->integer('quantity'); $table->decimal('total_price', 8, 2); $table->timestamps(); $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade'); }); } Tabel transactions akan menyimpan informasi tentang produk yang dibeli dan jumlah pembelian (quantity), serta total harga (total_price). Menjalankan Migration Setelah semua migration telah dibuat dan dimodifikasi, jalankan perintah berikut untuk membuat tabel di database: php artisan migrate Perintah ini akan membuat tabel products, categories, dan transactions di database yang sudah terhubung melalui file .env. Cara Menginstall dan Menggunakan Package Spatie Permission di Laravel Berikut adalah langkah-langkah untuk menginstall package Spatie Laravel Permission dalam proyek Laravel, lengkap dengan contoh koding. Install Package Spatie Laravel Permission Buka terminal, pastikan kamu berada di dalam direktori proyek Laravel, lalu jalankan perintah berikut untuk menginstall package Spatie Laravel Permission: composer require spatie/laravel-permission Setelah package berhasil diinstall, kamu perlu meng-publish file konfigurasi dan migration-nya dengan menjalankan perintah ini: php artisan vendor:publish --provider="Spatie\\\\Permission\\\\PermissionServiceProvider" Perintah ini akan menghasilkan file konfigurasi permission.php di direktori config dan file migration untuk tabel roles, permissions, dan tabel pivot untuk menghubungkan pengguna dengan role dan permission. Jalankan Migration Setelah mem-publish file konfigurasi, jalankan perintah berikut untuk membuat tabel yang diperlukan oleh Spatie di database: php artisan migrate Ini akan membuat tabel roles, permissions, dan tabel pivot seperti model_has_roles, model_has_permissions, dan role_has_permissions di database. Setup Model User Buka file User.php di direktori app/Models. Tambahkan trait HasRoles dari Spatie ke dalam model User agar pengguna dapat diberikan role dan permission. Berikut adalah contohnya: namespace App\\\\Models; use Illuminate\\\\Foundation\\\\Auth\\\\User as Authenticatable; use Spatie\\\\Permission\\\\Traits\\\\HasRoles; class User extends Authenticatable { use HasRoles; // kode lainnya } Dengan menambahkan trait HasRoles, kamu bisa mulai memberikan role dan permission kepada pengguna. Cara Menginstall Package Filament dan Membuat Filament Resource untuk Category, Product, User, Role, dan Permission Berikut ini adalah langkah-langkah lengkap untuk menginstall package Filament di proyek Laravel dan membuat resource admin untuk mengelola Category, Product, User, Role, dan Permission dengan Filament. Install Package Filament Untuk menginstall Filament, pastikan kamu sudah berada di dalam folder proyek Laravel di terminal. Jalankan perintah berikut untuk menginstall package Filament: composer require filament/filament Setelah package berhasil diinstall, jalankan perintah berikut untuk mem-publish aset dan konfigurasi Filament: php artisan filament:install Perintah ini akan mengatur konfigurasi awal Filament dan membuat dashboard admin yang bisa langsung diakses. Jalankan Migration Jika proses instalasi Filament sudah selesai, pastikan kamu menjalankan migration agar tabel-tabel yang dibutuhkan oleh Filament dapat terbentuk: php artisan migrate Membuat Filament Resource untuk Category Untuk membuat resource Category di Filament, gunakan perintah berikut di terminal: php artisan make:filament-resource Category Ini akan menghasilkan resource CategoryResource yang terletak di folder app/Filament/Resources/CategoryResource.php. Di file ini, kamu dapat menyesuaikan form dan tabel untuk pengelolaan data kategori. Contoh sederhana dari form dan tabel untuk Category bisa seperti ini: public static function form(Form $form): Form { return $form ->schema([ TextInput::make('name')->required(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name'), TextColumn::make('created_at')->dateTime(), ]) ->filters([]); } Membuat Filament Resource untuk Product Untuk membuat resource Product, jalankan perintah ini di terminal: php artisan make:filament-resource Product Setelah resource Product dibuat, kamu bisa menyesuaikan form dan tabel di file ProductResource.php. Misalnya: public static function form(Form $form): Form { return $form ->schema([ TextInput::make('name')->required(), TextInput::make('price')->numeric()->required(), Select::make('category_id') ->relationship('category', 'name')->required(), TextInput::make('stock')->numeric()->required(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name'), TextColumn::make('price')->money('USD'), TextColumn::make('stock'), TextColumn::make('category.name')->label('Category'), TextColumn::make('created_at')->dateTime(), ]) ->filters([]); } Membuat Filament Resource untuk User Untuk membuat resource User, jalankan perintah berikut: php artisan make:filament-resource User Sesuaikan form dan tabel di UserResource.php. Contoh implementasi form dan tabel untuk User: public static function form(Form $form): Form { return $form ->schema([ TextInput::make('name')->required(), TextInput::make('email')->email()->required(), PasswordInput::make('password')->required(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name'), TextColumn::make('email'), TextColumn::make('created_at')->dateTime(), ]) ->filters([]); } Membuat Filament Resource untuk Role Jika kamu menggunakan package Spatie untuk role management, berikut cara membuat resource Role: php artisan make:filament-resource Role Di dalam RoleResource.php, sesuaikan form dan tabel untuk mengelola role. Misalnya: public static function form(Form $form): Form { return $form ->schema([ TextInput::make('name')->required(), MultiSelect::make('permissions') ->relationship('permissions', 'name'), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name'), TextColumn::make('permissions.name')->label('Permissions')->limit(3), ]) ->filters([]); } Membuat Filament Resource untuk Permission Untuk resource Permission, jalankan perintah: php artisan make:filament-resource Permission Di dalam file PermissionResource.php, kamu bisa menyesuaikan form dan tabelnya sebagai berikut: public static function form(Form $form): Form { return $form ->schema([ TextInput::make('name')->required(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name'), TextColumn::make('created_at')->dateTime(), ]) ->filters([]); } Dengan mengikuti langkah-langkah di atas, kamu telah berhasil menginstall package Filament dan membuat resource untuk Category, Product, User, Role, dan Permission. Filament memudahkan pembuatan panel admin yang interaktif, lengkap dengan pengelolaan role dan permission menggunakan Spatie, sehingga pengembangan menjadi lebih cepat dan terstruktur. Membatasi Akses Dashboard Filament Hanya untuk User dengan Role Admin Setelah menambahkan Filament resource untuk Role dan memastikan role Admin sudah ada di database, kita akan memodifikasi model User agar hanya pengguna dengan role Admin yang dapat mengakses dashboard Filament. Untuk ini, kita akan menggunakan method canAccessPanel. Pastikan Trait HasRoles Sudah Ditambahkan di Model User Buka file app/Models/User.php dan tambahkan trait HasRoles dari Spatie Laravel Permission untuk mendukung fitur role management. Ini memungkinkan kita menggunakan method seperti hasRole untuk memeriksa apakah pengguna memiliki role tertentu. namespace App\\\\Models; use Illuminate\\\\Foundation\\\\Auth\\\\User as Authenticatable; use Spatie\\\\Permission\\\\Traits\\\\HasRoles; class User extends Authenticatable { use HasRoles; // Kode lainnya } Tambahkan Method canAccessPanel di Model User Filament akan memeriksa method canAccessPanel untuk menentukan apakah seorang pengguna memiliki akses ke dashboard. Tambahkan method ini di dalam model User untuk memverifikasi apakah pengguna memiliki role Admin. Buka file app/Models/User.php dan tambahkan method canAccessPanel berikut: public function canAccessPanel(): bool { return $this->hasRole('Admin'); } Method canAccessPanel akan mengembalikan true hanya jika pengguna memiliki role Admin. Dengan begitu, hanya pengguna dengan role Admin yang akan diizinkan untuk mengakses dashboard Filament. Cara Menguji Konfigurasi Pastikan role Admin sudah ada di database. Jika belum, tambahkan role ini menggunakan Filament dashboard atau melalui Tinker: php artisan tinker use App\\\\Models\\\\User; use Spatie\\\\Permission\\\\Models\\\\Role; Role::firstOrCreate(['name' => 'Admin']); $user = User::find(1); // Sesuaikan dengan ID user yang ingin diberi akses $user->assignRole('Admin'); Login ke dashboard Filament menggunakan akun pengguna yang memiliki role Admin. Jika konfigurasi canAccessPanel sudah benar, hanya user dengan role Admin yang dapat mengakses dashboard, sementara pengguna lain akan ditolak aksesnya. Dengan konfigurasi ini, akses ke dashboard Filament sekarang terbatas hanya untuk pengguna yang memiliki role Admin. Menambahkan Role Merchant dan Customer serta Beberapa Permission pada Proyek dengan Filament Resource Setelah sebelumnya menambahkan role Admin, kita akan menambahkan role Merchant dan Customer, serta beberapa permission yang relevan dengan proyek ini menggunakan Filament Resource. Dengan konfigurasi ini, kita dapat mengelola role dan permission dari dashboard Filament. Tambahkan Role Merchant dan Customer melalui Filament Pastikan RoleResource sudah dibuat dengan Filament. Untuk menambahkan role Merchant dan Customer, buka dashboard Filament di URL yang telah dikonfigurasi (biasanya /admin). Pada dashboard Filament: Masuk ke menu Roles yang disediakan oleh RoleResource.Klik tombol Create atau Add Role.Tambahkan role Merchant dengan mengisi nama role dan menyimpannya.Ulangi langkah yang sama untuk menambahkan role Customer. Tambahkan Permission Baru melalui Filament Jika sudah ada PermissionResource, kita bisa menambahkan permission yang dibutuhkan untuk setiap role. Pada dashboard Filament: Akses menu Permissions dari PermissionResource.Klik Create atau Add Permission untuk membuat permission baru.Tambahkan permission yang sesuai, seperti view products, manage own products, purchase products, dan view orders.Setelah menambahkan permission, klik Save. Mengatur Permission untuk Role Merchant dan Customer Setelah menambahkan role dan permission, kita bisa menetapkan permission yang sesuai untuk setiap role. Sebagai contoh: Merchant memiliki izin seperti view products dan manage own products.Customer memiliki izin view products dan purchase products. Pada dashboard Filament: Masuk ke menu Roles.Pilih role Merchant dan atur permissions-nya, seperti view products dan manage own products.Simpan perubahan.Pilih role Customer dan tetapkan permissions view products dan purchase products.Simpan perubahan. Menambahkan Role Merchant dan Customer serta Permissions Menggunakan Seeder (Opsional) Jika kamu ingin menambahkan role dan permission ini secara programatis, kamu bisa menggunakan seeder. Buat seeder RolePermissionSeeder jika belum ada: php artisan make:seeder RolePermissionSeeder Buka file database/seeders/RolePermissionSeeder.php dan tambahkan kode berikut untuk membuat role Merchant dan Customer serta permissions: namespace Database\\\\Seeders; use Illuminate\\\\Database\\\\Seeder; use Spatie\\\\Permission\\\\Models\\\\Role; use Spatie\\\\Permission\\\\Models\\\\Permission; class RolePermissionSeeder extends Seeder { public function run() { // Buat permissions $permissions = [ 'view products', 'manage own products', 'purchase products', 'view orders', ]; foreach ($permissions as $permission) { Permission::firstOrCreate(['name' => $permission]); } // Buat roles dan tetapkan permissions $adminRole = Role::firstOrCreate(['name' => 'Admin']); $merchantRole = Role::firstOrCreate(['name' => 'Merchant']); $customerRole = Role::firstOrCreate(['name' => 'Customer']); // Admin memiliki semua permissions $adminRole->syncPermissions(Permission::all()); // Merchant memiliki permission tertentu $merchantRole->syncPermissions([ 'view products', 'manage own products', 'view orders', ]); // Customer memiliki permission tertentu $customerRole->syncPermissions([ 'view products', 'purchase products', ]); } } Setelah menambahkan kode ini, jalankan seeder untuk membuat role dan permission secara otomatis di database: php artisan db:seed --class=RolePermissionSeeder Cara Membuat 10 Route Utama pada Proyek Toko Buah dan Melindungi dengan Role dan Permission Dalam proyek toko buah, kita akan membuat 10 route utama yang akan dilindungi menggunakan role dan permission yang telah ditambahkan sebelumnya. Role seperti Admin, Merchant, dan Customer akan memiliki akses terbatas sesuai dengan permission yang telah diatur. Di Laravel, middleware digunakan untuk memastikan hanya pengguna dengan role dan permission tertentu yang bisa mengakses route yang sudah ditentukan. Route untuk Menampilkan Produk (Dapat Diakses oleh Semua Role) Route ini digunakan untuk menampilkan daftar produk yang tersedia di toko. Role Admin, Merchant, dan Customer semuanya bisa mengakses halaman ini karena permission view products diberikan kepada semua role. Route::get('/products', function () { // Logic untuk menampilkan semua produk })->middleware('permission:view products'); Route untuk Menambah Produk (Hanya untuk Merchant dan Admin) Pada halaman ini, pengguna dengan role Admin dan Merchant dapat menambahkan produk baru ke toko. Hanya pengguna dengan role ini dan permission manage own products yang dapat mengakses halaman ini. Route::get('/products/create', function () { // Logic untuk menampilkan form tambah produk })->middleware(['role:Admin|Merchant', 'permission:manage own products']); Route untuk Menyimpan Produk Baru (Hanya untuk Merchant dan Admin) Route ini digunakan untuk menyimpan produk baru yang telah ditambahkan oleh Admin atau Merchant. Setelah mengisi form pada halaman sebelumnya, data produk akan disimpan melalui route ini. Route::post('/products', function () { // Logic untuk menyimpan produk baru })->middleware(['role:Admin|Merchant', 'permission:manage own products']); Route untuk Mengedit Produk (Hanya untuk Merchant dan Admin) Route ini mengizinkan pengguna dengan role Merchant dan Admin untuk mengedit produk yang ada. Hanya produk yang ditambahkan oleh mereka yang dapat diedit (untuk Merchant), atau semua produk (untuk Admin). Route::get('/products/{id}/edit', function ($id) { // Logic untuk menampilkan form edit produk })->middleware(['role:Admin|Merchant', 'permission:manage own products']); Route untuk Memperbarui Produk (Hanya untuk Merchant dan Admin) Setelah melakukan perubahan pada produk, route ini digunakan untuk memperbarui data produk di database. Hanya Merchant dan Admin yang memiliki akses untuk memperbarui produk. Route::put('/products/{id}', function ($id) { // Logic untuk memperbarui data produk })->middleware(['role:Admin|Merchant', 'permission:manage own products']); Route untuk Menghapus Produk (Hanya untuk Admin) Hanya pengguna dengan role Admin yang diizinkan untuk menghapus produk dari toko. Permission delete products dibutuhkan untuk melakukan tindakan ini. Route::delete('/products/{id}', function ($id) { // Logic untuk menghapus produk })->middleware(['role:Admin', 'permission:delete products']); Route untuk Menampilkan Daftar Pesanan (Hanya untuk Admin dan Merchant) Route ini digunakan untuk menampilkan daftar semua pesanan yang ada di sistem. Baik Admin maupun Merchant dapat melihat daftar pesanan, namun role Customer tidak memiliki akses. Route::get('/orders', function () { // Logic untuk menampilkan semua pesanan })->middleware(['role:Admin|Merchant', 'permission:view orders']); Route untuk Membuat Pesanan Baru (Hanya untuk Customer) Route ini digunakan oleh Customer untuk membuat pesanan baru. Setelah memilih produk, Customer akan diarahkan ke route ini untuk menyelesaikan pesanan mereka. Route::post('/orders', function () { // Logic untuk membuat pesanan baru })->middleware(['role:Customer', 'permission:purchase products']); Route untuk Menampilkan Detail Pesanan (Hanya untuk Customer dan Merchant) Customer dan Merchant dapat melihat detail dari pesanan tertentu. Merchant hanya bisa melihat pesanan yang terkait dengan produk yang mereka kelola, sementara Customer bisa melihat pesanan mereka sendiri. Route::get('/orders/{id}', function ($id) { // Logic untuk menampilkan detail pesanan })->middleware(['role:Customer|Merchant', 'permission:view orders']); Route untuk Mengelola Pengguna (Hanya untuk Admin) Hanya Admin yang memiliki akses untuk mengelola data pengguna lain di dalam sistem. Mereka dapat melihat daftar pengguna dan mengelola hak akses mereka. Route::get('/users', function () { // Logic untuk menampilkan daftar pengguna })->middleware(['role:Admin', 'permission:manage users']); Dengaan menggunakan middleware role dan permission, kita dapat mengamankan setiap route dalam aplikasi toko buah sesuai dengan hak akses yang diberikan kepada setiap pengguna. Pendekatan ini memungkinkan pembatasan akses yang terstruktur, memaastikan bahwa pengguna hanya bisa melakukan tindakan yang sesuai dengan role dan permission mereka. Penutup Laravel terus berkembang dan semakin populer berkat pembaruan-pembaruan menarik yang memudahkan developer dalam membangun aplikasi web yang kuat dan scalable. Fitur-fitur baru yang hadir secara berkala membuat Laravel tetap relevan dan menjadi pilihan utama bagi banyak developer di seluruh dunia. Untuk tetap mendapatkan ilmu terkini dan memaksimalkan kemampuan dalam menggunakan Laravel, pantau terus website BuildWithAngga. Di sana, kamu bisa menemukan banyak kelas gratis yang mencakup studi kasus menarik dan diajarkan oleh mentor berpengalaman. Selain itu, BuildWithAngga menawarkan akses seumur hidup, memungkinkan kamu untuk belajar kapan saja dan memastikan kamu selalu siap menghadapi tantangan baru di dunia web development.

Kelas 5 Contoh Penggunaan useState Pada Projek Website Booking Flight Ticket di BuildWithAngga

5 Contoh Penggunaan useState Pada Projek Website Booking Flight Ticket

useState adalah salah satu hooks yang sangat bermanfaat dalam framework React. Dengan menggunakan useState, developer dapat mengelola state atau keadaan di dalam komponen React dengan lebih efisien. Hal ini sangat membantu dalam membangun website modern yang dinamis, serta meningkatkan user experience (UX). Ketika developer ingin membuat komponen yang dapat merespon input pengguna atau perubahan data secara real-time, useState menjadi alat yang sangat tepat untuk digunakan. Menerapkan useState dalam Projek Booking Flight Ticket Dalam artikel ini, kita akan belajar cara menerapkan useState pada sebuah projek website booking flight ticket. Dengan menerapkan useState, kita dapat mengelola berbagai data dan interaksi pengguna, seperti memilih kota asal dan tujuan penerbangan, tanggal keberangkatan, jumlah penumpang, serta proses konfirmasi tiket. Penggunaan useState pada website booking semacam ini tidak hanya membuat website lebih interaktif, tetapi juga memudahkan pengguna untuk melakukan reservasi secara lebih intuitif. Tujuan dari artikel ini adalah memberikan gambaran umum tentang bagaimana useState dapat diterapkan pada projek nyata. Contoh-contoh yang dibahas akan menunjukkan penerapan praktis useState, sehingga Anda bisa lebih memahami cara penggunaannya dalam pengembangan aplikasi booking flight ticket. Cara Membuat Project React Booking Flight Ticket dengan Vite dan Menggunakan TypeScript Pada bagian ini, kita akan membahas cara membuat project React dengan Vite dan TypeScript yang berfungsi sebagai sistem booking flight ticket. Setiap langkah diberikan dengan contoh koding yang jelas untuk memudahkan Anda mengikuti prosesnya. 1. Instalasi Vite dengan TypeScript Langkah pertama dalam membuat project React adalah menginstal Vite dengan template TypeScript. Buka terminal dan jalankan perintah berikut: npm create vite@latest Saat diminta, berikan nama project, misalnya flight-booking-app, dan pilih React sebagai framework, lalu pilih TypeScript sebagai varian. Masuk ke direktori project dengan: cd flight-booking-app npm install Setelah itu, jalankan project dengan perintah: npm run dev Project Anda sekarang sudah berjalan dengan React dan TypeScript menggunakan Vite. 2. Struktur Folder Project Struktur folder yang dihasilkan oleh Vite sudah sangat ringkas. Folder src akan menjadi tempat Anda menyimpan komponen dan file lainnya. Berikut struktur dasarnya: flight-booking-app │ ├── src │ ├── components │ │ └── BookingForm.tsx │ └── App.tsx ├── public └── index.html Folder components akan digunakan untuk menyimpan komponen yang kita buat, seperti formulir booking penerbangan. 3. Membuat Komponen BookingForm Langkah berikutnya adalah membuat komponen BookingForm yang akan mengelola form booking penerbangan. Buat file baru di dalam folder components dengan nama BookingForm.tsx dan tambahkan kode berikut: import React, { useState } from 'react'; interface BookingFormProps {} const BookingForm: React.FC<BookingFormProps> = () => { const [departure, setDeparture] = useState(''); const [destination, setDestination] = useState(''); const [date, setDate] = useState(''); const [passengers, setPassengers] = useState(1); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); console.log({ departure, destination, date, passengers, }); }; return ( <form onSubmit={handleSubmit}> <div> <label>Departure City:</label> <input type="text" value={departure} onChange={(e) => setDeparture(e.target.value)} /> </div> <div> <label>Destination City:</label> <input type="text" value={destination} onChange={(e) => setDestination(e.target.value)} /> </div> <div> <label>Date of Flight:</label> <input type="date" value={date} onChange={(e) => setDate(e.target.value)} /> </div> <div> <label>Number of Passengers:</label> <input type="number" value={passengers} onChange={(e) => setPassengers(parseInt(e.target.value))} min="1" /> </div> <button type="submit">Book Flight</button> </form> ); }; export default BookingForm; Komponen ini membuat form sederhana untuk booking penerbangan yang melibatkan input untuk kota keberangkatan, kota tujuan, tanggal, dan jumlah penumpang. Setiap input diatur menggunakan useState untuk menyimpan nilai yang dimasukkan pengguna. 4. Menghubungkan BookingForm ke App.tsx Buka file App.tsx di dalam folder src dan impor komponen BookingForm. Berikut adalah contoh kodingnya: import React from 'react'; import BookingForm from './components/BookingForm'; const App: React.FC = () => { return ( <div> <h1>Flight Ticket Booking</h1> <BookingForm /> </div> ); }; export default App; Pada file ini, kita mengimpor komponen BookingForm dan menampilkannya di dalam komponen App. Komponen BookingForm kini dapat digunakan untuk mengelola input pengguna. 5. Menjalankan Project Setelah semua kode diimplementasikan, Anda dapat menjalankan project dan melihat bagaimana form booking penerbangan bekerja. Pastikan terminal Anda tetap terbuka, dan jalankan kembali perintah berikut: npm run dev Buka browser Anda dan kunjungi URL yang diberikan oleh Vite, biasanya di http://localhost:5173. Di sana, Anda akan melihat halaman form booking penerbangan, dan data yang Anda masukkan akan tercatat di console browser ketika Anda mengklik tombol Book Flight. Cara Membuat types.ts dan Data Dummy untuk Projek Website Booking Flight Ticket Dalam pembuatan projek React dengan TypeScript, penting untuk mendefinisikan tipe data yang digunakan agar mempermudah dalam mengelola state dan memastikan konsistensi data di seluruh aplikasi. Di sini kita akan membuat file types.ts yang berisi tipe data untuk form booking penerbangan, dan juga file data dummy untuk simulasi data penerbangan. 1. Membuat File types.ts Pertama, buat sebuah file bernama types.ts di dalam folder src. File ini akan berfungsi untuk mendefinisikan tipe data yang digunakan dalam projek. Berikut adalah contoh kode yang bisa dimasukkan ke dalam types.ts: export interface FlightTicket { id: number; departure: string; destination: string; date: string; passengers: number; } export interface City { id: number; name: string; } Pada contoh di atas, kita membuat dua interface, yaitu FlightTicket yang digunakan untuk mendefinisikan data dari tiket penerbangan, dan City untuk daftar kota yang tersedia. 2. Membuat Data Dummy Setelah mendefinisikan tipe data di types.ts, langkah berikutnya adalah membuat file data dummy yang berisi contoh data penerbangan dan daftar kota. Buat file baru bernama dummyData.ts di dalam folder src dan tambahkan data dummy berikut: import { FlightTicket, City } from './types'; export const flightTickets: FlightTicket[] = [ { id: 1, departure: 'Jakarta', destination: 'Bali', date: '2024-11-01', passengers: 2, }, { id: 2, departure: 'Surabaya', destination: 'Lombok', date: '2024-11-05', passengers: 1, }, { id: 3, departure: 'Medan', destination: 'Jakarta', date: '2024-11-10', passengers: 4, }, ]; export const cities: City[] = [ { id: 1, name: 'Jakarta', }, { id: 2, name: 'Bali', }, { id: 3, name: 'Surabaya', }, { id: 4, name: 'Lombok', }, { id: 5, name: 'Medan', }, ]; File dummyData.ts ini berisi array flightTickets yang berisi data penerbangan, dan array cities yang berisi daftar kota asal dan tujuan penerbangan. Dengan data dummy ini, Anda dapat menggunakannya untuk mensimulasikan input atau pilihan kota dalam form booking di aplikasi. 3. Menggunakan Data Dummy di Komponen Sekarang, kita bisa menggunakan data dummy ini di komponen React kita, khususnya pada komponen BookingForm yang sudah dibuat sebelumnya. Berikut adalah contoh cara mengimpor dan menggunakan data tersebut di dalam komponen: import React, { useState } from 'react'; import { cities } from '../dummyData'; const BookingForm: React.FC = () => { const [departure, setDeparture] = useState(''); const [destination, setDestination] = useState(''); const [date, setDate] = useState(''); const [passengers, setPassengers] = useState(1); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); console.log({ departure, destination, date, passengers, }); }; return ( <form onSubmit={handleSubmit}> <div> <label>Departure City:</label> <select value={departure} onChange={(e) => setDeparture(e.target.value)}> <option value="">Select City</option> {cities.map((city) => ( <option key={city.id} value={city.name}> {city.name} </option> ))} </select> </div> <div> <label>Destination City:</label> <select value={destination} onChange={(e) => setDestination(e.target.value)} > <option value="">Select City</option> {cities.map((city) => ( <option key={city.id} value={city.name}> {city.name} </option> ))} </select> </div> <div> <label>Date of Flight:</label> <input type="date" value={date} onChange={(e) => setDate(e.target.value)} /> </div> <div> <label>Number of Passengers:</label> <input type="number" value={passengers} onChange={(e) => setPassengers(parseInt(e.target.value))} min="1" /> </div> <button type="submit">Book Flight</button> </form> ); }; export default BookingForm; Pada contoh di atas, data dummy cities diimpor dari dummyData.ts dan digunakan untuk mengisi pilihan kota pada input select di form booking. Ini membuat form lebih dinamis dengan daftar kota yang tersedia untuk dipilih pengguna. 5 Contoh Penerapan useState Pada Projek Website Booking Flight Ticket Pada bagian ini, kita akan membahas beberapa contoh penerapan useState dari yang paling sederhana hingga yang lebih kompleks pada sebuah projek booking flight ticket. Setiap contoh dilengkapi dengan penjelasan dan contoh kode. 1. Mengelola Input Teks Sederhana dengan useState Pada kasus sederhana, kita dapat menggunakan useState untuk mengelola input teks dari pengguna. Misalnya, input untuk kota keberangkatan dan tujuan penerbangan. import React, { useState } from 'react'; const BookingForm: React.FC = () => { const [departure, setDeparture] = useState(''); const [destination, setDestination] = useState(''); return ( <form> <div> <label>Departure City:</label> <input type="text" value={departure} onChange={(e) => setDeparture(e.target.value)} /> </div> <div> <label>Destination City:</label> <input type="text" value={destination} onChange={(e) => setDestination(e.target.value)} /> </div> </form> ); }; export default BookingForm; Pada contoh ini, useState digunakan untuk menyimpan nilai dari input teks yang diambil dari pengguna. Ketika pengguna mengetik, nilai state diperbarui secara real-time. 2. Mengelola Input dengan Tipe Data Angka Selain mengelola input teks, useState juga dapat digunakan untuk mengelola input dengan tipe data angka, seperti jumlah penumpang. import React, { useState } from 'react'; const BookingForm: React.FC = () => { const [passengers, setPassengers] = useState(1); return ( <form> <div> <label>Number of Passengers:</label> <input type="number" value={passengers} onChange={(e) => setPassengers(parseInt(e.target.value))} min="1" /> </div> </form> ); }; export default BookingForm; Pada contoh ini, useState digunakan untuk menyimpan jumlah penumpang, yang dimasukkan melalui input bertipe angka (number). Nilai yang diinput akan diubah menjadi integer menggunakan parseInt. 3. Mengelola Pilihan Kota dengan Dropdown Berikut adalah contoh yang lebih kompleks, di mana kita menggunakan useState untuk mengelola pilihan kota menggunakan dropdown (select). import React, { useState } from 'react'; const cities = ['Jakarta', 'Bali', 'Surabaya', 'Lombok']; const BookingForm: React.FC = () => { const [departure, setDeparture] = useState(''); const [destination, setDestination] = useState(''); return ( <form> <div> <label>Departure City:</label> <select value={departure} onChange={(e) => setDeparture(e.target.value)}> <option value="">Select City</option> {cities.map((city) => ( <option key={city} value={city}> {city} </option> ))} </select> </div> <div> <label>Destination City:</label> <select value={destination} onChange={(e) => setDestination(e.target.value)} > <option value="">Select City</option> {cities.map((city) => ( <option key={city} value={city}> {city} </option> ))} </select> </div> </form> ); }; export default BookingForm; Pada contoh ini, useState digunakan untuk mengelola pilihan kota dari dropdown. Setiap kali pengguna memilih kota, nilai state akan diperbarui sesuai pilihan mereka. 4. Mengelola Tanggal Penerbangan dengan useState Penggunaan useState juga sangat membantu untuk mengelola input dengan tipe date, seperti tanggal penerbangan. import React, { useState } from 'react'; const BookingForm: React.FC = () => { const [date, setDate] = useState(''); return ( <form> <div> <label>Date of Flight:</label> <input type="date" value={date} onChange={(e) => setDate(e.target.value)} /> </div> </form> ); }; export default BookingForm; Pada contoh ini, useState mengelola input dengan tipe date. Ketika pengguna memilih tanggal, nilai state diperbarui dengan format string tanggal. 5. Mengelola Beberapa State Secara Bersamaan dan Mengirim Data Contoh berikut menggabungkan beberapa state sekaligus untuk mengelola seluruh data form dan menampilkan hasil input pengguna ketika form dikirim (submit). import React, { useState } from 'react'; const BookingForm: React.FC = () => { const [departure, setDeparture] = useState(''); const [destination, setDestination] = useState(''); const [date, setDate] = useState(''); const [passengers, setPassengers] = useState(1); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); console.log({ departure, destination, date, passengers, }); }; return ( <form onSubmit={handleSubmit}> <div> <label>Departure City:</label> <input type="text" value={departure} onChange={(e) => setDeparture(e.target.value)} /> </div> <div> <label>Destination City:</label> <input type="text" value={destination} onChange={(e) => setDestination(e.target.value)} /> </div> <div> <label>Date of Flight:</label> <input type="date" value={date} onChange={(e) => setDate(e.target.value)} /> </div> <div> <label>Number of Passengers:</label> <input type="number" value={passengers} onChange={(e) => setPassengers(parseInt(e.target.value))} min="1" /> </div> <button type="submit">Book Flight</button> </form> ); }; export default BookingForm; Pada contoh ini, kita menggabungkan beberapa state (departure, destination, date, dan passengers) dan mengirimkan seluruh data ketika form disubmit. Setelah pengguna mengisi semua input, data akan dikirim dan ditampilkan di console sebagai objek. Poin Penting Lanjutan dalam Memperdalam Framework React JS Setelah memahami dasar-dasar React seperti useState, ada beberapa konsep lanjutan yang penting untuk dipelajari guna memperdalam pemahaman dan keterampilan dalam menggunakan framework React JS. 1. useEffect useEffect adalah hooks yang digunakan untuk mengelola efek samping (side effects) dalam komponen React, seperti fetching data dari API, berinteraksi dengan browser API (misalnya localStorage), atau mengatur timer. Dengan mempelajari useEffect, Anda dapat memahami cara kerja lifecycle komponen React dan kapan harus menjalankan kode tertentu. 2. Context API Context API membantu dalam mengelola state global yang dapat diakses oleh banyak komponen tanpa perlu menggunakan props drilling (mengoper props dari komponen induk ke komponen anak). Ini sangat berguna ketika Anda bekerja dengan data yang perlu diakses di banyak bagian aplikasi, seperti data pengguna yang sedang login atau tema aplikasi. 3. React Router React Router adalah library yang digunakan untuk mengatur navigasi atau routing dalam aplikasi React. Dengan React Router, Anda bisa membuat navigasi yang lebih kompleks, seperti routing dinamis, nested routes, dan juga pengelolaan URL parameters untuk navigasi yang lebih user-friendly. 4. Custom Hooks Custom hooks memungkinkan Anda untuk membuat logika reusable dalam aplikasi React. Setelah memahami hooks bawaan seperti useState dan useEffect, belajar membuat custom hooks akan membantu Anda mengelola logika yang kompleks dan menggunakannya di beberapa komponen tanpa mengulang kode. 5. Optimisasi Kinerja (Performance Optimization) Memahami cara kerja virtual DOM dan bagaimana React melakukan rendering ulang sangat penting dalam optimisasi kinerja. Anda perlu mempelajari teknik-teknik seperti memoization dengan React.memo, useMemo, dan useCallback untuk mencegah rendering ulang yang tidak perlu dan menjaga aplikasi tetap responsif. 6. State Management dengan Redux atau Zustand Untuk aplikasi yang lebih besar, pengelolaan state yang lebih kompleks dapat menjadi tantangan. Library seperti Redux atau Zustand membantu dalam mengelola state global dengan cara yang lebih terstruktur dan scalable. Dengan mempelajari state management, Anda bisa mengelola data aplikasi secara efisien, terutama ketika data tersebut dibagikan di banyak komponen. 7. Error Boundaries Error Boundaries digunakan untuk menangkap error yang terjadi dalam komponen-komponen React. Ini sangat penting untuk mencegah aplikasi crash secara keseluruhan ketika terjadi error di satu bagian aplikasi. Mempelajari Error Boundaries akan membantu Anda mengelola error dengan lebih baik dan memberikan pengalaman pengguna yang lebih stabil. 8. TypeScript dengan React TypeScript memberikan tipe statis pada JavaScript, yang membantu dalam mencegah error dan membuat kode lebih mudah dipelihara. Memahami penggunaan TypeScript dengan React adalah langkah penting jika Anda ingin meningkatkan kualitas dan skalabilitas aplikasi, terutama pada proyek yang lebih besar. 9. Server-Side Rendering (SSR) dan Static Site Generation (SSG) Memahami konsep SSR dan SSG penting untuk meningkatkan kinerja dan SEO aplikasi React. Framework seperti Next.js memudahkan penerapan SSR dan SSG dalam aplikasi React, dan membantu membuat aplikasi lebih cepat diakses oleh pengguna dengan loading yang lebih cepat. 10. Testing dengan Jest dan React Testing Library Testing merupakan aspek penting dalam pengembangan aplikasi yang berkualitas. Dengan mempelajari testing di React, Anda dapat memastikan bahwa komponen dan fungsionalitas berjalan dengan benar. Library seperti Jest dan React Testing Library sangat populer dalam dunia React untuk melakukan unit testing dan integration testing. Dengan mempelajari poin-poin ini, Anda akan memiliki pemahaman yang lebih mendalam tentang bagaimana membangun aplikasi React yang lebih besar, lebih kompleks, dan lebih optimal. Kesimpulan dan Saran Memperdalam pemahaman tentang React JS membutuhkan waktu dan latihan yang konsisten. Dengan memahami konsep dasar seperti useState dan useEffect, serta mempelajari topik-topik lanjutan seperti Context API, React Router, dan optimisasi kinerja, Anda akan dapat membangun aplikasi web yang lebih efisien dan interaktif. Teruslah berlatih dan eksplorasi teknologi-teknologi baru dalam ekosistem React. Untuk mempercepat pembelajaran Anda, sangat disarankan untuk belajar langsung bersama mentor expert di BuildWithAngga. Dengan akses belajar selamanya, Anda bisa berkonsultasi langsung dengan mentor profesional, serta membangun portofolio modern yang siap digunakan untuk melamar pekerjaan atau proyek freelance. Mendapatkan dukungan dari komunitas yang tepat akan membantu Anda lebih percaya diri dalam menghadapi tantangan dalam dunia pengembangan web.

Kelas Tutorial TypeScript Pemula Bahasa Indonesia 2024 Part 1 di BuildWithAngga

Tutorial TypeScript Pemula Bahasa Indonesia 2024 Part 1

Saat ini, website telah menjadi media utama bagi perusahaan untuk mempromosikan jasa atau produk mereka secara online. Dengan adanya website, perusahaan dapat menjangkau audiens lebih luas, meningkatkan brand awareness, dan mendatangkan lebih banyak pelanggan. Sebagai platform digital, website memberikan fleksibilitas bagi perusahaan untuk menyampaikan informasi terbaru, menjual produk secara langsung, hingga melayani pelanggan dengan lebih efektif. Oleh karena itu, memiliki website yang baik menjadi kebutuhan penting bagi setiap bisnis di era digital ini. Membangun Website Modern dengan TypeScript Untuk dapat membangun website yang modern, mudah diperbesar, dan dimaintain, developer perlu memanfaatkan teknologi yang tepat. Salah satu solusi terbaik adalah menggunakan TypeScript. TypeScript adalah bahasa pemrograman yang memberikan keunggulan dari segi keandalan dan skalabilitas dibandingkan JavaScript biasa. Dengan TypeScript, developer dapat menulis kode yang lebih jelas, terstruktur, dan mudah di-maintenance, sehingga ketika aplikasi berkembang, kode tetap terjaga kualitasnya. Bagi pemula, memulai dengan TypeScript akan sangat bermanfaat karena memberikan kerangka yang lebih kuat untuk membangun website yang siap berkembang. Apa Itu TypeScript dan Manfaat Utama dalam Proyek Website Modern TypeScript adalah superset dari JavaScript, yang berarti TypeScript dibangun di atas JavaScript dengan menambahkan fitur baru, terutama sistem static typing atau pengetikan statis. TypeScript dirancang untuk membantu developer menulis kode yang lebih aman dan mudah dipelihara. Dalam proyek website modern, TypeScript menawarkan berbagai manfaat, salah satunya adalah kemampuan untuk mendeteksi kesalahan sebelum kode dijalankan. Dengan adanya type annotations, TypeScript memastikan bahwa variabel, fungsi, dan objek digunakan sesuai tipe yang telah ditentukan, sehingga mengurangi potensi bug yang sulit ditemukan pada JavaScript biasa. Manfaat utama menggunakan TypeScript dalam proyek website modern meliputi: Penulisan Kode yang Lebih Terstruktur: Dengan TypeScript, developer dapat menggunakan fitur seperti interfaces, types, dan enums untuk membuat struktur data yang lebih jelas.Peningkatan Kualitas Kode: Karena kesalahan terdeteksi lebih awal melalui pengetikan statis, kualitas kode menjadi lebih baik dan lebih sedikit kesalahan yang terjadi di tahap pengembangan.Skalabilitas: Ketika aplikasi tumbuh besar, kode yang ditulis dengan TypeScript lebih mudah untuk di-maintain dan dikembangkan, karena setiap bagian kode memiliki tipe data yang jelas.Dukungan Editor yang Lebih Baik: TypeScript terintegrasi dengan baik pada banyak editor dan memberikan fitur seperti auto-completion dan refactoring yang membuat pengalaman developer lebih nyaman dan produktif. Mengapa Developer Perlu Mencoba TypeScript Dibandingkan JavaScript JavaScript memang merupakan bahasa yang kuat dan fleksibel, namun TypeScript menawarkan beberapa kelebihan yang bisa membuat pengembangan lebih efisien dan aman. Salah satu alasan utama untuk mencoba TypeScript adalah keandalannya dalam mengelola proyek-proyek besar. Dalam JavaScript, pengetikan yang longgar (dynamic typing) bisa menyebabkan bug yang sulit dideteksi, terutama pada aplikasi yang kompleks dan terus berkembang. Dengan TypeScript, developer memiliki kontrol lebih besar melalui type checking, yang memastikan setiap variabel dan fungsi digunakan sesuai dengan tipe yang diharapkan. Selain itu, penggunaan TypeScript bisa membantu developer menjadi lebih produktif karena memberikan dokumentasi kode yang lebih jelas melalui types, serta meningkatkan kolaborasi dalam tim. Dengan tipe data yang eksplisit, developer lain bisa lebih cepat memahami kode yang ditulis, tanpa perlu membaca seluruh implementasi. TypeScript juga membantu dalam debugging, karena sebagian besar kesalahan dapat ditemukan pada saat kompilasi, sehingga mempercepat proses pengembangan secara keseluruhan. Bagi developer yang sudah terbiasa dengan JavaScript, beralih ke TypeScript tidak memerlukan pembelajaran dari awal, karena TypeScript sepenuhnya kompatibel dengan JavaScript. Ini membuat proses adopsi lebih mudah, sambil memberikan semua manfaat dari sistem pengetikan yang lebih ketat. Membuat Proyek Toko Online Sederhana Menggunakan TypeScript dan Node.js Untuk memulai proyek toko online sederhana menggunakan TypeScript dan Node.js, berikut adalah langkah-langkah yang bisa diikuti: 1. Inisialisasi Proyek Mulailah dengan membuat direktori proyek baru dan inisialisasi Node.js di dalamnya. Buka terminal dan jalankan perintah berikut: mkdir toko-online-typescript cd toko-online-typescript npm init -y 2. Install TypeScript dan Dependencies Instal TypeScript dan beberapa dependency dasar seperti express untuk membangun server, serta ts-node dan nodemon untuk memudahkan proses pengembangan. npm install typescript ts-node-dev express Setelah itu, jalankan perintah untuk menginisialisasi file konfigurasi TypeScript. npx tsc --init 3. Struktur Folder Proyek Buat struktur folder sederhana untuk proyek ini: toko-online-typescript/ │ ├── src/ │ ├── index.ts │ ├── routes/ │ └── productRoutes.ts │ ├── package.json └── tsconfig.json 4. Buat Server Dasar dengan Express Di dalam folder src, buat file index.ts yang berfungsi sebagai titik masuk aplikasi. import express, { Application } from 'express'; import productRoutes from './routes/productRoutes'; const app: Application = express(); const PORT = 3000; app.use(express.json()); app.use('/products', productRoutes); app.listen(PORT, () => { console.log(`Server running on <http://localhost>:${PORT}`); }); 5. Buat Rute Produk Selanjutnya, buat file productRoutes.ts di dalam folder routes untuk mengelola rute produk. import { Router } from 'express'; const router = Router(); let products = [ { id: 1, name: 'Laptop', price: 15000000 }, { id: 2, name: 'Smartphone', price: 5000000 } ]; // Mendapatkan semua produk router.get('/', (req, res) => { res.json(products); }); // Menambahkan produk baru router.post('/', (req, res) => { const newProduct = { id: products.length + 1, ...req.body }; products.push(newProduct); res.status(201).json(newProduct); }); export default router; 6. Jalankan Proyek Untuk menjalankan proyek, tambahkan skrip di dalam package.json: "scripts": { "dev": "ts-node-dev src/index.ts" } Sekarang jalankan proyek dengan perintah berikut: npm run dev Proyek toko online sederhana Anda sekarang dapat diakses di http://localhost:3000/products. Mengatur TypeScript Configuration dan Menjalankan TypeScript Untuk mengonfigurasi TypeScript dalam proyek Anda, ada beberapa langkah yang perlu dilakukan, mulai dari pengaturan file konfigurasi hingga menjalankan proyek menggunakan TypeScript. 1. Buat File tsconfig.json Ketika Anda menjalankan perintah npx tsc --init, sebuah file tsconfig.json akan otomatis dibuat. Berikut adalah konfigurasi dasar untuk proyek Node.js menggunakan TypeScript: { "compilerOptions": { "target": "ES6", "module": "commonjs", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src/**/*"], "exclude": ["node_modules"] } Penjelasan konfigurasi: target: Menentukan versi ECMAScript yang akan digunakan (dalam hal ini ES6).module: Menentukan format modul yang digunakan, dalam Node.js kita gunakan commonjs.outDir: Lokasi output file JavaScript setelah TypeScript dikompilasi.rootDir: Lokasi file TypeScript Anda.strict: Mengaktifkan pemeriksaan ketat untuk membantu mencegah bug.esModuleInterop: Memastikan kompatibilitas antara modul CommonJS dan ECMAScript. 2. Menjalankan TypeScript dengan tsc Untuk mengompilasi file TypeScript ke JavaScript, jalankan perintah berikut di terminal: npx tsc Perintah ini akan mengkompilasi seluruh file TypeScript dalam folder src menjadi file JavaScript, yang akan disimpan di folder dist sesuai pengaturan tsconfig.json. 3. Menjalankan Proyek Setelah Dikompilasi Setelah file dikompilasi, Anda bisa menjalankan aplikasi dengan Node.js langsung dari folder dist: node dist/index.js Proyek akan berjalan seperti biasa, tetapi sekarang Anda menjalankannya dari versi JavaScript yang dihasilkan oleh TypeScript. Dengan langkah-langkah di atas, Anda telah berhasil mengatur TypeScript dan menjalankan proyek toko online sederhana menggunakan TypeScript. Cara Menerapkan Basic Types di TypeScript Dalam TypeScript, tipe data dasar seperti number, string, boolean, array, tuple, dan enum dapat digunakan untuk memastikan bahwa variabel, fungsi, dan objek digunakan sesuai tipe yang diharapkan. Berikut adalah langkah-langkah untuk menerapkan setiap tipe dasar ini dengan contoh koding yang lengkap. Menggunakan Tipe Number Tipe number digunakan untuk angka, baik bilangan bulat maupun desimal. Di TypeScript, kita bisa secara eksplisit mendefinisikan variabel sebagai number. let price: number = 15000; let discount: number = 20.5; console.log(price); // Output: 15000 console.log(discount); // Output: 20.5 Menggunakan Tipe String Tipe string digunakan untuk menyimpan teks atau nilai string. Kita bisa menggunakan tanda kutip tunggal atau ganda untuk mendefinisikan string. let productName: string = 'Laptop'; let productDescription: string = "Laptop high-end untuk gaming"; console.log(productName); // Output: Laptop console.log(productDescription); // Output: Laptop high-end untuk gaming Menggunakan Tipe Boolean Tipe boolean hanya memiliki dua nilai: true atau false. Tipe ini berguna untuk logika kondisi. let isAvailable: boolean = true; let isDiscounted: boolean = false; console.log(isAvailable); // Output: true console.log(isDiscounted); // Output: false Menggunakan Tipe Array Tipe array digunakan untuk menyimpan beberapa nilai dengan tipe yang sama. Di TypeScript, kita bisa menentukan tipe elemen array menggunakan notasi type[] atau Array<type>. let productPrices: number[] = [15000, 25000, 35000]; let productNames: Array<string> = ['Laptop', 'Smartphone', 'Tablet']; console.log(productPrices); // Output: [15000, 25000, 35000] console.log(productNames); // Output: ['Laptop', 'Smartphone', 'Tablet'] Menggunakan Tipe Tuple Tipe tuple memungkinkan kita menyimpan array dengan elemen yang memiliki tipe data berbeda, namun dalam urutan tertentu. let productDetail: [string, number, boolean] = ['Laptop', 15000, true]; console.log(productDetail); // Output: ['Laptop', 15000, true] // Elemen pertama adalah string, kedua adalah number, dan ketiga adalah boolean Menggunakan Tipe Enum Tipe enum adalah cara untuk memberi nama sekelompok nilai numerik atau string, sehingga kita bisa merujuk pada nilai-nilai ini dengan nama yang lebih mudah dibaca. enum ProductCategory { Electronics, Furniture, Clothing } let productCategory: ProductCategory = ProductCategory.Electronics; console.log(productCategory); // Output: 0 (karena enums dimulai dari 0 secara default) Kita juga bisa menentukan nilai secara eksplisit pada enum. enum PaymentStatus { Pending = 'PENDING', Completed = 'COMPLETED', Failed = 'FAILED' } let currentStatus: PaymentStatus = PaymentStatus.Completed; console.log(currentStatus); // Output: COMPLETED Dengan langkah-langkah di atas, Anda sekarang dapat menerapkan berbagai tipe data dasar seperti number, string, boolean, array, tuple, dan enum dalam proyek TypeScript Anda. Tipe-tipe ini membantu memastikan bahwa kode Anda lebih aman dan mudah dipelihara. Cara Menerapkan Function, Typing Function Parameters, Default Parameters, Optional Parameters, dan Arrow Functions di TypeScript Dalam TypeScript, function dapat ditulis dengan tipe data yang jelas untuk parameter dan nilai kembalian. Selain itu, TypeScript mendukung parameter default dan opsional, serta arrow functions. Berikut adalah langkah-langkah lengkap dengan contoh koding. Menerapkan Function dengan Typing pada Parameters Saat mendefinisikan fungsi di TypeScript, kita dapat menentukan tipe parameter dan nilai yang akan dikembalikan oleh fungsi tersebut. Ini memberikan kejelasan dan keamanan dalam proses pengembangan. function calculateTotalPrice(price: number, quantity: number): number { return price * quantity; } let totalPrice = calculateTotalPrice(15000, 3); console.log(totalPrice); // Output: 45000 Di sini, tipe number ditentukan untuk parameter price dan quantity, serta fungsi ini akan mengembalikan nilai bertipe number. Menerapkan Default Parameters TypeScript memungkinkan kita menetapkan nilai default untuk parameter fungsi. Jika parameter ini tidak diberikan nilai saat fungsi dipanggil, maka nilai default akan digunakan. function applyDiscount(price: number, discount: number = 10): number { return price - (price * discount) / 100; } let priceWithDiscount = applyDiscount(20000); console.log(priceWithDiscount); // Output: 18000 Dalam contoh di atas, jika nilai discount tidak diberikan, maka secara otomatis akan menggunakan nilai default 10. Menerapkan Optional Parameters TypeScript juga mendukung parameter opsional, yang berarti parameter tersebut tidak harus disertakan ketika fungsi dipanggil. Untuk mendefinisikan parameter opsional, tambahkan tanda tanya ? setelah nama parameter. function calculateShippingCost(weight: number, expedited?: boolean): number { if (expedited) { return weight * 100; } else { return weight * 50; } } let normalShipping = calculateShippingCost(2); let expeditedShipping = calculateShippingCost(2, true); console.log(normalShipping); // Output: 100 console.log(expeditedShipping); // Output: 200 Dalam contoh ini, parameter expedited bersifat opsional. Jika tidak diberikan, fungsi akan tetap berjalan dengan asumsi expedited bernilai false. Menerapkan Arrow Functions Arrow functions adalah sintaks yang lebih singkat untuk mendefinisikan fungsi, sering digunakan dalam konteks callbacks atau fungsi sederhana. const calculateTax = (price: number): number => { return price * 0.1; } let tax = calculateTax(10000); console.log(tax); // Output: 1000 Arrow function ini memiliki sintaks yang lebih ringkas dan bisa sangat berguna ketika ingin menulis fungsi singkat atau anonim. Untuk arrow functions yang sangat sederhana, jika hanya ada satu baris kode yang langsung mengembalikan nilai, kita bisa menghilangkan tanda kurung kurawal dan kata kunci return. const calculateDiscount = (price: number, discount: number): number => price - (price * discount) / 100; let discountedPrice = calculateDiscount(20000, 15); console.log(discountedPrice); // Output: 17000 Arrow function ini langsung mengembalikan hasil perhitungan tanpa perlu menulis return dan kurung kurawal. Latihan Menerapkan Basic Types dan Function pada Proyek Toko Online Dalam latihan ini, kita akan membuat proyek toko online sederhana dengan beberapa fitur dasar. Kita akan menggunakan berbagai tipe dasar TypeScript seperti number, string, boolean, array, tuple, dan enum, serta mendefinisikan beberapa fungsi yang mencakup penggunaan typing pada parameter, default parameter, optional parameter, dan arrow functions. 1. Inisialisasi Proyek Mulai dengan menginisialisasi proyek baru: mkdir toko-online cd toko-online npm init -y npm install typescript ts-node-dev express npx tsc --init Buat folder src dan tambahkan file index.ts sebagai entry point. 2. Struktur Data untuk Produk Buat tipe dasar untuk produk menggunakan interface. Setiap produk akan memiliki id, name, price, stock, dan category. enum ProductCategory { Electronics = 'Electronics', Clothing = 'Clothing', Groceries = 'Groceries' } interface Product { id: number; name: string; price: number; stock: number; category: ProductCategory; } let products: Product[] = [ { id: 1, name: 'Laptop', price: 15000, stock: 10, category: ProductCategory.Electronics }, { id: 2, name: 'T-Shirt', price: 200, stock: 50, category: ProductCategory.Clothing }, { id: 3, name: 'Rice', price: 100, stock: 100, category: ProductCategory.Groceries } ]; Di sini, kita menggunakan enum untuk kategori produk dan interface untuk mendefinisikan tipe produk. Array products menyimpan daftar produk yang ada. 3. Menambahkan Fungsi untuk Mengelola Produk Sekarang buat fungsi untuk menambah, mengedit, dan menghapus produk. Kita akan menggunakan typing pada parameter dan nilai kembalian. function addProduct(newProduct: Product): Product[] { products.push(newProduct); return products; } function updateProduct(id: number, updatedFields: Partial<Product>): Product[] { const productIndex = products.findIndex((product) => product.id === id); if (productIndex !== -1) { products[productIndex] = { ...products[productIndex], ...updatedFields }; } return products; } function deleteProduct(id: number): Product[] { products = products.filter((product) => product.id !== id); return products; } Fungsi addProduct menambahkan produk baru ke dalam daftar.Fungsi updateProduct memungkinkan pembaruan hanya pada field tertentu dengan menggunakan Partial<Product>.Fungsi deleteProduct menghapus produk berdasarkan ID. 4. Menghitung Total Harga dengan Fungsi Menggunakan Parameter Default dan Opsional Sekarang buat fungsi yang menghitung total harga pembelian. Kita akan menggunakan parameter default untuk diskon dan parameter opsional untuk jumlah barang yang dibeli. function calculateTotalPrice(price: number, quantity: number = 1, discount?: number): number { let total = price * quantity; if (discount) { total = total - (total * discount) / 100; } return total; } const totalPrice1 = calculateTotalPrice(15000, 2); const totalPrice2 = calculateTotalPrice(200, 5, 10); console.log(totalPrice1); // Output: 30000 console.log(totalPrice2); // Output: 900 Fungsi ini menggunakan: Parameter quantity dengan nilai default 1, sehingga jika pengguna tidak memasukkan jumlah, fungsi akan menganggap jumlahnya 1.Parameter opsional discount untuk menghitung harga setelah diskon jika tersedia. 5. Menampilkan Produk dengan Fungsi dan Arrow Function Buat fungsi untuk menampilkan produk yang tersedia dan gunakan arrow function untuk menyaring produk berdasarkan kategori. const displayAvailableProducts = (): void => { products.forEach((product) => { console.log(`Product: ${product.name}, Price: ${product.price}, Stock: ${product.stock}, Category: ${product.category}`); }); }; const filterProductsByCategory = (category: ProductCategory): Product[] => { return products.filter((product) => product.category === category); }; displayAvailableProducts(); const electronicsProducts = filterProductsByCategory(ProductCategory.Electronics); console.log(electronicsProducts); displayAvailableProducts menggunakan void sebagai tipe kembalian karena tidak mengembalikan apa pun.filterProductsByCategory adalah arrow function yang menyaring produk berdasarkan kategori tertentu. 6. Menjalankan Proyek Tambahkan skrip berikut di dalam package.json untuk menjalankan proyek: "scripts": { "dev": "ts-node-dev src/index.ts" } Kemudian jalankan proyek dengan: npm run dev Contoh 5 Kesalahan Umum Ketika Menggunakan TypeScript Meskipun TypeScript membantu menulis kode yang lebih aman dan terstruktur, ada beberapa kesalahan umum yang sering terjadi, terutama bagi pemula. Berikut ini adalah 5 contoh kesalahan saat menggunakan TypeScript, lengkap dengan penjelasan dan contoh koding. 1. Mengabaikan Strict Typing Salah satu kesalahan umum adalah mengabaikan sistem pengetikan ketat TypeScript dengan tidak mendefinisikan tipe data secara eksplisit. Ini bisa menghilangkan manfaat utama dari TypeScript. let productName = 'Laptop'; // TypeScript secara otomatis menganggap ini string productName = 123; // Kesalahan: Type 'number' tidak bisa ditetapkan ke type 'string' Solusi: Selalu mendefinisikan tipe data secara eksplisit untuk menghindari masalah ini. let productName: string = 'Laptop'; productName = 'Smartphone'; // Tidak ada kesalahan karena tipe tetap string 2. Tidak Menangani Nilai undefined dan null Ketika bekerja dengan nilai yang mungkin undefined atau null, mengabaikan kemungkinan ini bisa menyebabkan kesalahan pada runtime. TypeScript sering kali mengharuskan kita untuk menangani nilai tersebut dengan baik. function getProductById(id: number): string | undefined { if (id === 1) { return 'Laptop'; } } let product = getProductById(2); console.log(product.toUpperCase()); // Kesalahan: Tidak bisa membaca 'toUpperCase' dari 'undefined' Solusi: Gunakan pengecekan untuk menangani kemungkinan undefined atau null. let product = getProductById(2); if (product) { console.log(product.toUpperCase()); // Tidak ada kesalahan } 3. Salah Menggunakan any Menggunakan tipe any terlalu sering dapat merusak keamanan tipe di TypeScript, karena kita kehilangan manfaat dari pengetikan yang ketat. let product: any = 'Laptop'; product = 123; // Tidak ada kesalahan, tetapi bisa menyebabkan bug di runtime Solusi: Hindari penggunaan any sebanyak mungkin, dan gunakan tipe yang lebih spesifik. let product: string = 'Laptop'; // product = 123; // Kesalahan: Type 'number' tidak bisa ditetapkan ke type 'string' 4. Salah Menggunakan Union Types Union types memungkinkan variabel untuk memiliki lebih dari satu tipe, tetapi penggunaan yang salah bisa menimbulkan kebingungan. function displayProductInfo(product: string | number) { console.log(product.toUpperCase()); // Kesalahan: Property 'toUpperCase' tidak ada di type 'number' } Solusi: Gunakan pengecekan tipe (type guard) sebelum memanggil metode atau melakukan operasi yang spesifik untuk tipe tertentu. function displayProductInfo(product: string | number) { if (typeof product === 'string') { console.log(product.toUpperCase()); // Tidak ada kesalahan } else { console.log(product); // Menangani tipe number } } 5. Salah Mendefinisikan Object dan Array Types Kesalahan umum lainnya adalah mendefinisikan tipe objek atau array tanpa spesifik, seperti menggunakan object atau any[] yang terlalu umum dan tidak aman. let product: object = { name: 'Laptop', price: 15000 }; console.log(product.name); // Kesalahan: Property 'name' tidak ada di type 'object' Solusi: Gunakan interface atau type untuk mendefinisikan struktur objek atau array dengan lebih jelas. interface Product { name: string; price: number; } let product: Product = { name: 'Laptop', price: 15000 }; console.log(product.name); // Tidak ada kesalahan Kesimpulan dan Saran Dalam mempelajari TypeScript, ada banyak kesalahan yang bisa dihindari dengan memahami konsep-konsep dasarnya secara mendalam. Dengan pengetikan yang ketat dan berbagai fitur canggih, TypeScript membantu programmer menulis kode yang lebih aman, terstruktur, dan mudah dikelola dalam proyek besar. Bagi programmer pemula maupun berpengalaman, belajar dan berlatih TypeScript akan memperkaya kemampuan dalam membangun aplikasi web modern. Jika Anda ingin memperdalam pemahaman Anda tentang TypeScript atau teknologi web lainnya, belajar bareng mentor expert di BuildWithAngga bisa menjadi pilihan terbaik. Anda akan mendapatkan akses materi seumur hidup, konsultasi langsung dengan mentor berpengalaman, serta kesempatan membangun portfolio modern yang siap digunakan untuk bekerja. Dengan bimbingan dari para ahli, Anda bisa lebih percaya diri dalam mengembangkan kemampuan dan meraih karier yang sukses di dunia programming.

Kelas Tutorial React JS Pemula: Belajar useState dan useEffect Hooks Pada Web Point of Sales di BuildWithAngga

Tutorial React JS Pemula: Belajar useState dan useEffect Hooks Pada Web Point of Sales

Di era digital saat ini, setiap perusahaan wajib memiliki website modern dan dinamis untuk memberikan pengalaman terbaik kepada pengguna. Website yang lambat atau sulit digunakan dapat membuat calon pelanggan pergi ke kompetitor. Website modern tidak hanya tentang tampilan yang menarik, tapi juga bagaimana fungsinya dapat memberikan kenyamanan saat digunakan, mulai dari kecepatan loading hingga interaksi yang mulus di setiap fitur. React JS adalah salah satu framework yang diciptakan untuk memenuhi kebutuhan pembuatan website dinamis tersebut. Dengan berbagai fitur menarik yang tersedia, seperti useState dan useEffect, React memungkinkan developer untuk mengelola state dan side effects dengan lebih mudah. React JS dirancang agar developer dapat membangun komponen-komponen UI yang efisien dan interaktif, dengan memanfaatkan hooks seperti useState untuk mengelola data atau nilai di dalam aplikasi dan useEffect untuk menangani efek samping yang terjadi saat rendering. Hooks seperti useState dan useEffect membantu membuat kode menjadi lebih bersih dan lebih mudah dipelihara, terutama dalam web development modern yang membutuhkan responsivitas tinggi. Dengan React, developer dapat membuat website yang dinamis, efisien, dan mudah dikembangkan seiring pertumbuhan bisnis. Apa Itu useState dan useEffect pada React JS? useState dan useEffect adalah dua hook yang paling umum digunakan dalam React JS. Keduanya memiliki peran penting dalam membantu developer mengelola state dan side effects saat membangun aplikasi berbasis komponen. useState adalah hook yang digunakan untuk mengelola state di dalam komponen React. Ketika kita membuat komponen dalam React, terkadang kita perlu menyimpan dan mengubah data seiring berjalannya waktu, misalnya data input dari pengguna atau hasil perhitungan. Dengan useState, developer dapat membuat variabel yang dinamis, dan ketika nilai tersebut berubah, React akan secara otomatis merender ulang komponen yang bersangkutan. Di sisi lain, useEffect adalah hook yang digunakan untuk menangani efek samping dalam komponen. Efek samping ini bisa berupa pengambilan data dari API, manipulasi DOM secara langsung, atau berinteraksi dengan layanan eksternal. Dengan useEffect, kita bisa menentukan kapan sebuah fungsi dijalankan setelah rendering, sehingga membantu sinkronisasi antara komponen dan sumber data eksternal. Fitur yang Dapat Dibangun dengan useState dan useEffect di Website Point of Sales Pada website point of sales (POS), useState dan useEffect bisa dimanfaatkan untuk membangun berbagai fitur dinamis yang mendukung operasional penjualan. Berikut beberapa contoh fitur yang dapat dikembangkan: Manajemen Keranjang Belanja: Dengan useState, kita bisa mengelola daftar barang yang ditambahkan ke dalam keranjang oleh pengguna. Setiap kali pengguna menambah atau menghapus produk, nilai keranjang akan diperbarui secara otomatis, dan tampilan total harga akan berubah sesuai dengan barang yang ada.Mengambil Data Produk dari API: Dengan useEffect, kita bisa mengambil data produk secara real-time dari API. Misalnya, ketika pengguna membuka halaman POS, useEffect akan digunakan untuk memuat daftar produk terbaru dari server sehingga pengguna selalu mendapatkan informasi stok terkini.Hitung Total Harga Transaksi: Menggunakan useState untuk menyimpan nilai total transaksi, kita bisa membuat fitur yang menghitung harga total berdasarkan produk yang dipilih oleh pengguna. Jika pengguna menambah produk ke keranjang, total harga akan langsung diperbarui.Notifikasi Perubahan Stok: Dengan kombinasi useState dan useEffect, kita bisa membuat notifikasi yang muncul ketika ada perubahan stok produk. Misalnya, ketika sebuah produk hampir habis, useEffect bisa memicu notifikasi untuk mengingatkan pengguna atau kasir. Kedua hook ini sangat membantu dalam membangun aplikasi yang dinamis dan responsif, seperti website POS, yang memerlukan interaksi real-time dengan pengguna dan sistem backend. Tata Cara Membuat Projek Website Point of Sales Menggunakan Terminal dan Vite Untuk memulai proyek website point of sales (POS) menggunakan React dengan Vite, kita bisa mengikuti beberapa langkah dasar berikut ini. Dalam tutorial ini, kita akan menginstal Vite sebagai tool build yang cepat untuk proyek React. Langkah 1: Install Node.js dan npm Sebelum memulai, pastikan kamu sudah menginstal Node.js dan npm (Node Package Manager) di komputermu. Node.js diperlukan untuk menjalankan perintah-perintah JavaScript di terminal, sementara npm digunakan untuk mengelola package yang dibutuhkan oleh proyek React. Untuk memeriksa apakah Node.js sudah terinstal, jalankan perintah ini di terminal: node -v Jika Node.js sudah terinstal, akan muncul versi Node.js yang sedang kamu gunakan. Jika belum, silakan download dan instal dari website resmi Node.js. Langkah 2: Membuat Proyek Baru dengan Vite Setelah Node.js terinstal, kamu bisa membuat proyek React baru dengan menggunakan Vite. Buka terminal, lalu jalankan perintah berikut: npm create vite@latest Setelah itu, kamu akan diminta untuk memberikan nama proyek. Misalnya, kamu bisa menamainya pos-website. Kemudian pilih template React ketika ditanya tentang jenis proyek yang ingin kamu buat. Vite akan menginstal semua dependensi dasar yang dibutuhkan untuk memulai proyek React. Langkah 3: Masuk ke Direktori Proyek Setelah proses instalasi selesai, masuk ke direktori proyek dengan perintah: cd pos-website Langkah 4: Instal Dependensi Proyek Di dalam direktori proyek, kamu perlu menginstal semua dependensi yang dibutuhkan untuk menjalankan proyek Vite React. Jalankan perintah berikut: npm install Ini akan menginstal semua package yang diperlukan seperti React, React DOM, dan dependensi Vite lainnya. Langkah 5: Menjalankan Proyek di Server Lokal Setelah instalasi selesai, kamu bisa langsung menjalankan proyek POS dengan perintah berikut: npm run dev Vite akan memulai server lokal untuk proyekmu, dan kamu bisa melihat proyek berjalan di browser melalui URL http://localhost:3000 atau alamat lain yang ditampilkan di terminal. Langkah 6: Struktur Folder Dasar Proyek Vite Setelah berhasil menjalankan proyek, kamu akan melihat struktur folder dasar seperti ini: index.html: file utama untuk struktur HTML dasar.src: folder ini berisi file-file JavaScript dan komponen React. Di dalam folder src, kamu akan menemukan App.jsx yang menjadi file utama untuk komponen React. Langkah 7: Membuat Komponen untuk Fitur POS Untuk membangun fitur point of sales, kita bisa mulai dengan membuat beberapa komponen React. Sebagai contoh, buat komponen ProductList.jsx di dalam folder src/components: mkdir src/components touch src/components/ProductList.jsx Di dalam file ProductList.jsx, kamu bisa mulai menuliskan kode untuk menampilkan daftar produk. Tata Cara Menerapkan useState pada Website Point of Sales Berikut adalah panduan untuk menerapkan useState pada aplikasi website point of sales menggunakan React. Dalam contoh ini, kita akan menggunakan useState untuk mengelola daftar produk dan menambahkan fitur sederhana seperti menambahkan produk ke keranjang. Kami akan menggunakan data dummy untuk mencontohkan bagaimana useState bekerja. Langkah 1: Buat Data Dummy Produk Pertama, buat data dummy produk di dalam komponen. Kamu bisa menyimpan data ini di dalam komponen utama atau dalam file terpisah. Untuk keperluan demo, kita akan membuatnya langsung di dalam komponen. const products = [ { id: 1, name: "Product A", price: 100 }, { id: 2, name: "Product B", price: 200 }, { id: 3, name: "Product C", price: 300 }, ]; Langkah 2: Buat Komponen ProductList Selanjutnya, buat komponen ProductList yang akan menampilkan daftar produk. Kita akan menggunakan useState untuk menyimpan data produk yang ada di keranjang. import React, { useState } from "react"; const ProductList = () => { const [cart, setCart] = useState([]); const addToCart = (product) => { setCart([...cart, product]); }; return ( <div> <h3>Daftar Produk</h3> {products.map((product) => ( <div key={product.id}> <p>{product.name}</p> <p>Harga: {product.price}</p> <button onClick={() => addToCart(product)}>Tambah ke Keranjang</button> </div> ))} <h3>Keranjang</h3> {cart.length > 0 ? ( cart.map((item, index) => ( <div key={index}> <p>{item.name}</p> <p>Harga: {item.price}</p> </div> )) ) : ( <p>Keranjang kosong</p> )} </div> ); }; export default ProductList; Langkah 3: Menggunakan useState untuk Menambah Produk ke Keranjang Dalam komponen di atas, kita menggunakan useState untuk membuat state cart yang akan menyimpan produk yang ditambahkan ke keranjang. Fungsi setCart digunakan untuk memperbarui daftar produk di keranjang ketika pengguna mengklik tombol "Tambah ke Keranjang". Dengan memanggil setCart([...cart, product]), kita menambahkan produk baru ke dalam array cart tanpa mengubah data sebelumnya. Langkah 4: Tampilkan Data Keranjang Setelah menambahkan produk ke keranjang, kita menampilkan produk yang ada di dalam keranjang di bagian bawah halaman. Jika keranjang kosong, akan muncul pesan "Keranjang kosong". Jika ada produk, produk tersebut akan ditampilkan bersama dengan harganya. Dengan cara ini, useState membantu kita mengelola data secara dinamis sesuai interaksi pengguna, seperti menambahkan produk ke keranjang dalam aplikasi point of sales. Tata Cara Menerapkan useEffect pada Website Point of Sales Berikut adalah panduan untuk menerapkan useEffect pada website point of sales (POS) menggunakan React. Dalam contoh ini, kita akan menggunakan useEffect untuk melakukan simulasi pengambilan data produk dari API menggunakan data dummy. Langkah 1: Buat Komponen ProductList dengan useEffect Buat komponen React bernama ProductList di mana kita akan menggunakan useEffect untuk memuat data produk saat komponen pertama kali dirender. import React, { useState, useEffect } from "react"; const ProductList = () => { const [products, setProducts] = useState([]); useEffect(() => { // Simulasi pengambilan data produk dari API menggunakan data dummy const fetchProducts = async () => { const dummyProducts = [ { id: 1, name: "Product A", price: 100 }, { id: 2, name: "Product B", price: 200 }, { id: 3, name: "Product C", price: 300 }, ]; // Simulasi waktu tunggu seperti ketika mengambil data dari API setTimeout(() => { setProducts(dummyProducts); }, 1000); }; fetchProducts(); }, []); // Dependency array kosong untuk menjalankan useEffect hanya sekali saat komponen di-mount return ( <div> <h3>Daftar Produk</h3> {products.length > 0 ? ( products.map((product) => ( <div key={product.id}> <p>{product.name}</p> <p>Harga: {product.price}</p> </div> )) ) : ( <p>Loading produk...</p> )} </div> ); }; export default ProductList; Langkah 2: Memahami useEffect untuk Pengambilan Data Dalam contoh di atas, useEffect digunakan untuk menjalankan fungsi fetchProducts hanya satu kali ketika komponen pertama kali dimuat. Ini dilakukan dengan memberikan array dependency kosong [] pada useEffect, yang berarti efek ini hanya akan dijalankan sekali ketika komponen pertama kali dirender. Fungsi fetchProducts mensimulasikan pengambilan data dari API dengan menggunakan data dummy. Dalam contoh ini, kita menggunakan setTimeout untuk mensimulasikan keterlambatan pengambilan data, seolah-olah kita sedang memanggil API dan menunggu respons. Setelah satu detik, kita memperbarui state products dengan data dummy. Langkah 3: Tampilkan Data Produk Setelah data produk diambil, kita memeriksa apakah products memiliki data. Jika data sudah dimuat, produk ditampilkan di layar. Jika data masih dalam proses diambil, kita menampilkan pesan "Loading produk..." untuk memberikan feedback visual kepada pengguna. Dengan useEffect, kita dapat mengatur logika pengambilan data secara mudah tanpa harus menulis banyak kode tambahan. Hook ini sangat bermanfaat dalam pengembangan aplikasi point of sales yang memerlukan pengambilan data produk secara real-time dari API atau sumber data lainnya. Apa Itu Dependency Array pada useEffect? Dependency array pada useEffect adalah parameter opsional yang digunakan untuk mengontrol kapan efek di dalam useEffect akan dijalankan ulang. Dengan menambahkan nilai-nilai tertentu ke dalam array ini, React akan memantau perubahan pada nilai-nilai tersebut dan menjalankan efek kembali hanya ketika salah satu nilai berubah. Jika dependency array kosong ([]), useEffect hanya akan dijalankan sekali ketika komponen pertama kali dirender (atau di-mount). Jika ada nilai di dalam array, useEffect akan dijalankan setiap kali salah satu nilai tersebut berubah. Ini sangat berguna untuk mengoptimalkan kinerja komponen agar tidak terus-menerus menjalankan efek yang tidak perlu. Contoh Penerapan Dependency Array pada Website Point of Sales Pada website point of sales (POS), useEffect dengan dependency array dapat digunakan untuk berbagai kebutuhan, seperti: Mengambil Data Produk Sekali Saat Halaman Dimuat Dalam aplikasi POS, kita sering kali perlu mengambil data produk dari API atau server. Dengan dependency array kosong, kita bisa memastikan pengambilan data hanya dilakukan sekali saat halaman pertama kali dimuat, sehingga data produk tidak perlu diambil ulang setiap kali komponen dirender ulang.Menampilkan Detail Produk Berdasarkan Pilihan Pengguna Jika pengguna mengklik salah satu produk dari daftar, kita dapat menggunakan dependency array untuk menjalankan efek setiap kali produk yang dipilih berubah. Sebagai contoh, ketika pengguna memilih produk, data produk tersebut bisa di-fetch atau diambil dari state yang ada, kemudian useEffect akan dijalankan untuk menampilkan detail produk.Memperbarui Harga Total Berdasarkan Daftar Produk di Keranjang Dalam kasus lain, jika aplikasi POS memiliki fitur keranjang belanja, useEffect dengan dependency array dapat digunakan untuk menghitung total harga setiap kali daftar produk di keranjang berubah. Dependency array akan memuat data keranjang, dan useEffect akan dijalankan ulang setiap kali ada perubahan di dalam keranjang, sehingga total harga selalu diperbarui. Apakah Syarat Menerapkan Dependency Array dengan Value yang Tidak Kosong Harus Melakukan Fetch Endpoint API? Penerapan dependency array dengan value yang tidak kosong dalam useEffect tidak harus selalu terkait dengan melakukan fetch endpoint API. Dependency array berfungsi untuk mengontrol kapan useEffect akan dijalankan ulang berdasarkan perubahan nilai di dalam array tersebut. Ini berarti dependency array bisa memantau state, props, atau nilai apa pun yang berubah dalam komponen, dan tidak harus selalu berhubungan dengan API call. Sebagai contoh, dependency array bisa digunakan untuk memperbarui UI berdasarkan interaksi pengguna atau perubahan state tanpa melibatkan API sama sekali. Berikut ini adalah contoh di mana dependency array digunakan tanpa melakukan fetch dari API: import React, { useState, useEffect } from "react"; const ProductList = () => { const [selectedProduct, setSelectedProduct] = useState(null); const [message, setMessage] = useState(""); useEffect(() => { // Set pesan ketika produk yang dipilih berubah if (selectedProduct) { setMessage(`Anda memilih ${selectedProduct.name}`); } }, [selectedProduct]); // Dependency array memantau perubahan nilai selectedProduct const products = [ { id: 1, name: "Product A", price: 100 }, { id: 2, name: "Product B", price: 200 }, { id: 3, name: "Product C", price: 300 }, ]; const handleProductClick = (product) => { setSelectedProduct(product); }; return ( <div> <h3>Daftar Produk</h3> {products.map((product) => ( <div key={product.id} style={{ border: "1px solid #ccc", padding: "10px", margin: "10px 0" }}> <p>{product.name}</p> <p>Harga: {product.price}</p> <button onClick={() => handleProductClick(product)}>Pilih Produk</button> </div> ))} <div> <h3>Pesan</h3> <p>{message}</p> </div> </div> ); }; export default ProductList; Pada contoh di atas, useEffect digunakan untuk menampilkan pesan setiap kali pengguna memilih produk dari daftar. Dependency array berisi selectedProduct, yang berarti useEffect hanya akan dijalankan ketika nilai selectedProduct berubah, yaitu ketika pengguna memilih produk baru. Ini tidak melibatkan fetch API, namun tetap menggunakan dependency array untuk mengontrol kapan efek dijalankan. Dalam kasus lain, dependency array juga bisa digunakan untuk memantau nilai seperti props yang diberikan dari komponen induk, atau state internal yang berubah karena interaksi pengguna. Jadi, penggunaan dependency array tidak terbatas pada fetch data dari API, melainkan bisa untuk segala jenis perubahan nilai dalam aplikasi React. Tata Cara Menerapkan useEffect dengan Dependency Array pada Website Point of Sales Dalam contoh ini, kita akan menggunakan useEffect dengan dependency array yang nilainya akan berubah setiap kali pengguna mengklik produk. Ketika produk diklik, nilai dalam dependency array akan diperbarui, dan detail produk yang dipilih akan ditampilkan di sebelah kanan layar. Langkah 1: Siapkan Komponen dan Data Produk Buat komponen ProductList yang memuat daftar produk menggunakan data dummy. Produk yang dipilih oleh pengguna akan disimpan dalam state selectedProduct, dan detail produk tersebut akan ditampilkan setelah nilai dependency array berubah. import React, { useState, useEffect } from "react"; const ProductList = () => { const [products, setProducts] = useState([]); const [selectedProduct, setSelectedProduct] = useState(null); const [productDetails, setProductDetails] = useState(null); useEffect(() => { // Simulasi pengambilan data produk dari API const dummyProducts = [ { id: 1, name: "Product A", price: 100, description: "Deskripsi Product A" }, { id: 2, name: "Product B", price: 200, description: "Deskripsi Product B" }, { id: 3, name: "Product C", price: 300, description: "Deskripsi Product C" }, ]; // Simulasi delay untuk pengambilan data setTimeout(() => { setProducts(dummyProducts); }, 1000); }, []); // Dependency array kosong untuk dijalankan sekali saat komponen di-mount // useEffect dengan dependency array yang memantau perubahan selectedProduct useEffect(() => { if (selectedProduct) { // Menampilkan detail produk berdasarkan produk yang dipilih setProductDetails({ name: selectedProduct.name, price: selectedProduct.price, description: selectedProduct.description, }); } }, [selectedProduct]); // Efek ini akan dijalankan setiap kali selectedProduct berubah return ( <div style={{ display: "flex" }}> <ProductCards products={products} setSelectedProduct={setSelectedProduct} /> <ProductDetails product={productDetails} /> </div> ); }; Langkah 2: Komponen untuk Menampilkan Daftar Produk Buat komponen ProductCards yang menampilkan daftar produk dari props dan memungkinkan pengguna memilih produk. const ProductCards = ({ products, setSelectedProduct }) => { const handleProductClick = (product) => { setSelectedProduct(product); }; return ( <div style={{ width: "50%" }}> <h3>Daftar Produk</h3> {products.length > 0 ? ( products.map((product) => ( <div key={product.id} style={{ border: "1px solid #ccc", padding: "10px", margin: "10px 0" }}> <p>{product.name}</p> <p>Harga: {product.price}</p> <button onClick={() => handleProductClick(product)}>Lihat Detail</button> </div> )) ) : ( <p>Loading produk...</p> )} </div> ); }; Langkah 3: Komponen untuk Menampilkan Detail Produk Setelah produk dipilih, detail produk akan ditampilkan di bagian kanan layar berdasarkan produk yang dipilih. const ProductDetails = ({ product }) => { return ( <div style={{ width: "50%", paddingLeft: "20px" }}> <h3>Detail Produk</h3> {product ? ( <div> <p><strong>{product.name}</strong></p> <p>Harga: {product.price}</p> <p>Deskripsi: {product.description}</p> </div> ) : ( <p>Pilih produk untuk melihat detail</p> )} </div> ); }; Langkah 4: Memahami Dependency Array Dalam contoh ini: useEffect pertama digunakan untuk memuat data produk saat komponen pertama kali dirender. Dependency array kosong ([]) memastikan efek hanya dijalankan sekali.useEffect kedua digunakan untuk memantau perubahan nilai selectedProduct. Setiap kali pengguna mengklik produk, selectedProduct diperbarui, yang memicu useEffect kedua untuk memperbarui state productDetails. Dependency array [selectedProduct] memastikan bahwa efek hanya dijalankan ketika ada perubahan pada selectedProduct. Dengan cara ini, setiap kali pengguna mengklik sebuah produk, detail produk akan muncul di sebelah kanan layar berkat perubahan pada dependency array. Beberapa Contoh Fitur Point of Sales yang Tidak Seharusnya Menggunakan useEffect atau Dependency Array Meskipun useEffect dengan dependency array sangat berguna dalam banyak kasus, ada situasi di mana menggunakan useState saja adalah pendekatan yang lebih baik, terutama jika fitur yang diimplementasikan tidak memerlukan efek samping. Dalam aplikasi point of sales (POS), ada beberapa fitur yang cukup sederhana untuk dikelola dengan useState saja tanpa perlu menggunakan useEffect. Penggunaan useEffect secara berlebihan dapat membuat kode lebih kompleks daripada yang diperlukan. Berikut adalah beberapa contoh fitur point of sales yang lebih baik dikelola dengan useState saja tanpa useEffect. Contoh 1: Mengelola Kuantitas Produk dalam Keranjang Belanja Pada aplikasi POS, ketika pengguna menambah atau mengurangi kuantitas produk dalam keranjang, kita tidak memerlukan useEffect karena perubahan kuantitas dapat langsung dikelola dengan useState. import React, { useState } from "react"; const Cart = () => { const [cartItems, setCartItems] = useState([ { id: 1, name: "Product A", quantity: 1, price: 100 }, { id: 2, name: "Product B", quantity: 2, price: 200 }, ]); const increaseQuantity = (id) => { const updatedCartItems = cartItems.map(item => item.id === id ? { ...item, quantity: item.quantity + 1 } : item ); setCartItems(updatedCartItems); }; const decreaseQuantity = (id) => { const updatedCartItems = cartItems.map(item => item.id === id && item.quantity > 1 ? { ...item, quantity: item.quantity - 1 } : item ); setCartItems(updatedCartItems); }; return ( <div> <h3>Keranjang Belanja</h3> {cartItems.map(item => ( <div key={item.id}> <p>{item.name}</p> <p>Harga: {item.price}</p> <p>Kuantitas: {item.quantity}</p> <button onClick={() => increaseQuantity(item.id)}>Tambah</button> <button onClick={() => decreaseQuantity(item.id)}>Kurangi</button> </div> ))} </div> ); }; export default Cart; Penjelasan: Di sini, useState digunakan untuk mengelola daftar produk dan kuantitasnya dalam keranjang.Tidak diperlukan useEffect karena setiap perubahan langsung dapat dikelola melalui fungsi handler (increaseQuantity dan decreaseQuantity) yang mengubah state. Contoh 2: Menampilkan Total Harga Berdasarkan Produk di Keranjang Untuk menghitung total harga barang-barang dalam keranjang, kita bisa langsung menghitungnya di dalam JSX tanpa perlu memisahkan logika ke dalam useEffect. Ini adalah contoh di mana menggunakan useState saja sudah cukup, karena perhitungan total harga adalah hasil langsung dari state yang ada. import React, { useState } from "react"; const CartWithTotal = () => { const [cartItems, setCartItems] = useState([ { id: 1, name: "Product A", quantity: 1, price: 100 }, { id: 2, name: "Product B", quantity: 2, price: 200 }, ]); const totalPrice = cartItems.reduce((total, item) => total + item.price * item.quantity, 0); return ( <div> <h3>Keranjang Belanja</h3> {cartItems.map(item => ( <div key={item.id}> <p>{item.name}</p> <p>Harga: {item.price}</p> <p>Kuantitas: {item.quantity}</p> </div> ))} <h3>Total Harga: {totalPrice}</h3> </div> ); }; export default CartWithTotal; Penjelasan: Tidak ada kebutuhan untuk menggunakan useEffect di sini karena total harga dapat dihitung langsung dari state yang ada setiap kali komponen dirender.Menggunakan useState untuk menyimpan item keranjang sudah cukup, dan perhitungan total harga bisa dilakukan dalam JSX, sehingga lebih sederhana dan efisien. Contoh 3: Menampilkan Pesan Berdasarkan Kondisi Simpel Jika Anda ingin menampilkan pesan sederhana berdasarkan apakah keranjang belanja kosong atau tidak, ini juga tidak memerlukan useEffect. Anda bisa memeriksa kondisi langsung di JSX menggunakan useState. import React, { useState } from "react"; const CartMessage = () => { const [cartItems, setCartItems] = useState([]); return ( <div> <h3>Keranjang Belanja</h3> {cartItems.length > 0 ? ( cartItems.map(item => ( <div key={item.id}> <p>{item.name}</p> <p>Harga: {item.price}</p> <p>Kuantitas: {item.quantity}</p> </div> )) ) : ( <p>Keranjang kosong</p> )} </div> ); }; export default CartMessage; Penjelasan: Tidak diperlukan useEffect karena kondisi apakah keranjang kosong atau tidak bisa langsung diperiksa berdasarkan panjang array cartItems.useState sudah cukup untuk mengelola state dan menampilkan pesan yang sesuai di JSX tanpa efek samping tambahan. Mengapa Tidak Menggunakan useEffect? useEffect sebaiknya digunakan ketika Anda membutuhkan efek samping seperti pengambilan data dari API, melakukan sinkronisasi state dengan sumber eksternal, atau mengatur event listener.Dalam contoh-contoh di atas, tidak ada efek samping yang terjadi. Semua perubahan state langsung berpengaruh pada rendering komponen, sehingga tidak perlu ada penggunaan useEffect. 3 Contoh Kesalahan Ketika Menerapkan useEffect pada Proyek Point of Sales Dalam pengembangan aplikasi dengan React, khususnya aplikasi point of sales (POS), useEffect sering kali disalahgunakan atau diterapkan secara tidak tepat, yang dapat menyebabkan masalah performa, logika bisnis yang salah, atau bug sulit terdeteksi. Berikut adalah tiga kesalahan umum dalam penerapan useEffect di proyek POS, serta solusi untuk memperbaikinya. Kesalahan 1: Memasukkan State yang Tidak Perlu ke dalam Dependency Array Kesalahan umum adalah memasukkan state yang selalu berubah secara terus-menerus ke dalam dependency array, yang menyebabkan useEffect dijalankan berulang-ulang dan tidak efisien. Contoh Koding: import React, { useState, useEffect } from "react"; const Cart = () => { const [cartItems, setCartItems] = useState([]); const [totalPrice, setTotalPrice] = useState(0); useEffect(() => { // Menghitung total harga setiap kali ada perubahan pada cartItems setTotalPrice(cartItems.reduce((total, item) => total + item.price * item.quantity, 0)); }, [cartItems, totalPrice]); // Kesalahan: memasukkan totalPrice ke dalam dependency array const addItemToCart = (newItem) => { setCartItems([...cartItems, newItem]); }; return ( <div> <h3>Total Harga: {totalPrice}</h3> <button onClick={() => addItemToCart({ id: 1, name: "Product A", price: 100, quantity: 1 })}> Tambah Produk A </button> </div> ); }; export default Cart; Kesalahan: Memasukkan totalPrice ke dalam dependency array menyebabkan useEffect terus dijalankan ulang setiap kali totalPrice berubah, padahal totalPrice sudah diperbarui di dalam efek tersebut. Solusi: Hapus totalPrice dari dependency array karena kita hanya perlu memantau perubahan pada cartItems. Perbaikan Koding: useEffect(() => { setTotalPrice(cartItems.reduce((total, item) => total + item.price * item.quantity, 0)); }, [cartItems]); // Dependency hanya pada cartItems Kesalahan 2: Menggunakan useEffect untuk Operasi yang Bisa Dilakukan Langsung di JSX Kesalahan lainnya adalah menggunakan useEffect untuk tugas yang sebenarnya bisa langsung dilakukan di JSX, seperti perhitungan sederhana atau render kondisional. Ini memperumit kode dan tidak efisien. Contoh Koding: import React, { useState, useEffect } from "react"; const CartMessage = () => { const [cartItems, setCartItems] = useState([]); const [message, setMessage] = useEffect(""); useEffect(() => { if (cartItems.length > 0) { setMessage("Keranjang Anda tidak kosong"); } else { setMessage("Keranjang kosong"); } }, [cartItems]); // Kesalahan: Menggunakan useEffect untuk mengatur pesan sederhana return ( <div> <h3>{message}</h3> </div> ); }; export default CartMessage; Kesalahan: Menggunakan useEffect untuk mengatur pesan sederhana seperti "Keranjang kosong" atau "Keranjang tidak kosong", yang sebenarnya bisa langsung dikelola di JSX. Solusi: Alihkan logika ini langsung ke dalam JSX tanpa menggunakan useEffect, karena tidak ada efek samping yang perlu ditangani. Perbaikan Koding: const CartMessage = () => { const [cartItems, setCartItems] = useState([]); return ( <div> <h3>{cartItems.length > 0 ? "Keranjang Anda tidak kosong" : "Keranjang kosong"}</h3> </div> ); }; Kesalahan 3: Menjalankan Fetch Data Berulang Kali Tanpa Menggunakan Dependency Array yang Tepat Kesalahan yang sering terjadi adalah tidak menetapkan dependency array dengan benar pada useEffect, yang menyebabkan fetch data atau efek lainnya dijalankan berulang-ulang setiap kali komponen dirender. Contoh Koding: import React, { useState, useEffect } from "react"; const ProductList = () => { const [products, setProducts] = useState([]); useEffect(() => { // Mengambil data produk setiap kali komponen dirender fetch("<https://api.example.com/products>") .then((response) => response.json()) .then((data) => setProducts(data)); }); // Kesalahan: Tidak ada dependency array, menyebabkan fetch terus-menerus return ( <div> <h3>Daftar Produk</h3> {products.map((product) => ( <div key={product.id}> <p>{product.name}</p> <p>Harga: {product.price}</p> </div> ))} </div> ); }; export default ProductList; Kesalahan: Karena tidak ada dependency array, useEffect dijalankan setiap kali komponen dirender, sehingga fetch data terus-menerus dilakukan, yang mengakibatkan beban berlebih pada aplikasi dan server. Solusi: Gunakan dependency array kosong [] jika Anda hanya ingin fetch data satu kali ketika komponen pertama kali di-mount. Perbaikan Koding: useEffect(() => { fetch("<https://api.example.com/products>") .then((response) => response.json()) .then((data) => setProducts(data)); }, []); // Dependency array kosong agar fetch hanya dijalankan sekali Kesimpulan Kesalahan pertama adalah memasukkan state yang tidak perlu ke dalam dependency array, yang menyebabkan efek dijalankan berulang-ulang.Kesalahan kedua adalah menggunakan useEffect untuk tugas sederhana yang bisa langsung ditangani dalam JSX.Kesalahan ketiga adalah tidak menggunakan dependency array dengan benar, yang menyebabkan efek seperti fetch data dijalankan terus-menerus. Dengan memahami kesalahan umum ini, Anda dapat mengoptimalkan penggunaan useEffect di proyek React, khususnya dalam aplikasi point of sales, dan memastikan performa serta logika aplikasi tetap efisien dan mudah di-maintain. Kesimpulan dan Penutup Dalam mengembangkan aplikasi point of sales atau proyek lain dengan React, memahami bagaimana cara yang benar dalam menggunakan useEffect dan useState sangatlah penting untuk memastikan performa aplikasi yang optimal dan efisien. Menghindari kesalahan umum, seperti memasukkan state yang tidak perlu dalam dependency array atau menjalankan logika sederhana di dalam useEffect, akan membuat kode Anda lebih bersih dan mudah dikelola. Setiap orang dapat belajar lebih dalam tentang pengembangan aplikasi dan React di BuildWithAngga. Dengan bergabung, Anda akan mendapatkan berbagai manfaat, termasuk konsultasi dengan mentor yang berpengalaman, akses materi selamanya, serta kesempatan untuk membangun portofolio terbaik yang akan meningkatkan peluang Anda dalam mendapatkan pekerjaan di dunia industri teknologi. Temukan pengalaman belajar yang menyenangkan dan terstruktur bersama BuildWithAngga, di mana Anda dapat mempercepat karir Anda di dunia web development dan teknologi lainnya.

Kelas Tutorial Next JS 14 Pemula: Cara Mapping Data dan Mengirim Data ke Component di BuildWithAngga

Tutorial Next JS 14 Pemula: Cara Mapping Data dan Mengirim Data ke Component

Next.js adalah salah satu framework JavaScript yang sangat populer dan sering digunakan oleh developer dalam membangun website modern. Mengapa? Karena Next.js tidak hanya menawarkan performa tinggi, tetapi juga memudahkan developer dalam mengelola data dan state yang berbeda-beda. Ketika membangun sebuah website yang kompleks, seperti toko online atau aplikasi dengan banyak interaksi, menggunakan Next.js dapat menjadi pilihan terbaik. Framework ini memungkinkan pengelolaan data secara efisien, membuat pengelolaan state lebih mudah, serta memberikan fitur-fitur seperti rendering server-side yang meningkatkan performa dan SEO website. Next.js juga memudahkan developer untuk membuat website dengan struktur yang terorganisir dengan baik, sehingga cocok untuk proyek-proyek yang skalanya besar maupun kecil. Selain itu, framework ini sangat mendukung modularitas, di mana kita bisa dengan mudah membagi komponen-komponen website menjadi bagian yang lebih kecil, membuatnya lebih mudah untuk dikelola dan dikembangkan. Mengirim Data Antar Komponen di Next.js Dalam pengembangan website modern, sering kali kita bekerja dengan data dalam jumlah besar. Data tersebut harus dikelola dan ditampilkan dengan baik pada tampilan yang diinginkan. Di sinilah Next.js sangat membantu. Salah satu kemampuan dasar yang perlu dikuasai ketika menggunakan Next.js adalah cara mapping atau memetakan data dan mengirimkan data tersebut ke komponen yang berbeda. Artikel ini akan membahas bagaimana kita dapat memanfaatkan dummy data dalam Next.js dan bagaimana mengirim data tersebut antar komponen. Mapping data adalah proses di mana kita mengambil data dari sumber, baik itu dari API atau data statis seperti dummy data, dan menampilkannya dalam komponen. Setiap komponen bisa menerima data tersebut sebagai props dan menggunakannya sesuai kebutuhan, seperti untuk menampilkan daftar produk, kategori, atau informasi lainnya. Dengan memahami cara mengirim data ke komponen yang berbeda di Next.js, kita dapat membangun aplikasi web yang lebih dinamis dan responsif terhadap perubahan data. Membuat Proyek Website Sewa Rumah Menggunakan Next.js 14 dengan npm Untuk memulai proyek website sewa rumah menggunakan Next.js 14, pertama-tama kita perlu menginstal Next.js menggunakan npm. Berikut langkah-langkah lengkap untuk membuat proyek ini: npx create-next-app@latest website-sewa-rumah cd website-sewa-rumah npm install npm run dev Perintah di atas akan membuat proyek baru bernama website-sewa-rumah, menginstal semua dependensi, dan menjalankan proyek di mode pengembangan. Setelah berhasil, Anda dapat mengakses proyek tersebut melalui http://localhost:3000. Dalam proyek ini, kita akan membuat beberapa halaman penting seperti daftar rumah yang disewakan, kategori, testimoni dari penyewa, dan transaksi. Seluruh data akan dikelola melalui komponen-komponen terpisah agar lebih modular dan mudah dikelola. Membuat Data Dummy untuk Categories, Testimonials, Houses, dan Transactions Dalam proyek website sewa rumah, kita sering kali memerlukan data dummy untuk membantu dalam pengembangan dan testing. Data dummy ini dapat mencakup kategori rumah, testimoni penyewa, daftar rumah yang disewakan, dan transaksi yang terjadi. Berikut ini contoh bagaimana cara membuat data dummy di Next.js. Langkah pertama: Buat file data.js atau dummyData.js di folder root atau dalam folder data untuk menyimpan data dummy: // dummyData.js export const categories = [ { id: 1, name: 'Rumah Minimalis', description: 'Desain modern dan minimalis.' }, { id: 2, name: 'Rumah Klasik', description: 'Desain klasik dengan material kayu.' }, { id: 3, name: 'Rumah Modern', description: 'Rumah dengan teknologi pintar.' } ]; export const testimonials = [ { id: 1, name: 'Budi', message: 'Pelayanan sangat memuaskan!' }, { id: 2, name: 'Siti', message: 'Rumah bersih dan nyaman.' }, { id: 3, name: 'Andi', message: 'Proses sewa cepat dan mudah.' } ]; export const houses = [ { id: 1, name: 'Rumah Mewah di Jakarta', price: 100000000, category: 3, description: 'Rumah dengan teknologi pintar.' }, { id: 2, name: 'Rumah Minimalis di Bandung', price: 50000000, category: 1, description: 'Desain modern dan minimalis.' }, { id: 3, name: 'Rumah Klasik di Yogyakarta', price: 75000000, category: 2, description: 'Desain klasik dengan material kayu.' } ]; export const transactions = [ { id: 1, houseId: 1, userId: 1, date: '2024-10-01', amount: 100000000 }, { id: 2, houseId: 2, userId: 2, date: '2024-09-15', amount: 50000000 } ]; Langkah kedua: Import data dummy tersebut ke komponen yang membutuhkan. Misalnya, jika Anda ingin menampilkan daftar rumah yang disewakan, Anda bisa mengimpor data houses dari dummyData.js. // pages/index.js import { houses, categories } from '../dummyData'; export default function Home() { return ( <div> <h1>Daftar Rumah yang Disewakan</h1> <ul> {houses.map((house) => ( <li key={house.id}> <h2>{house.name}</h2> <p>Kategori: {categories.find(cat => cat.id === house.category)?.name}</p> <p>Harga: Rp {house.price}</p> <p>Deskripsi: {house.description}</p> </li> ))} </ul> </div> ); } Cara Melakukan Mapping pada Data dan Validasi Ketika Data Kosong Ketika melakukan mapping pada data, terutama dalam proyek Next.js, Anda bisa memanfaatkan fungsi map untuk mengiterasi data yang ada. Selain itu, penting untuk memastikan bahwa ketika data kosong, aplikasi tetap menampilkan informasi yang tepat. Misalnya, jika tidak ada rumah yang tersedia, kita dapat memberikan pesan yang menyatakan bahwa belum ada data terbaru. Berikut adalah cara lengkap melakukan mapping pada data dengan validasi data kosong: Langkah pertama: Import data dummy seperti houses, categories, dan testimonials, lalu lakukan mapping menggunakan fungsi map. Langkah kedua: Tambahkan validasi untuk mengecek apakah data tersebut kosong. Jika kosong, tampilkan pesan bahwa belum ada data terbaru. Berikut contoh koding lengkap: // pages/index.js import { houses, categories, testimonials } from '../dummyData'; export default function Home() { return ( <div> <h1>Daftar Rumah yang Disewakan</h1> {houses.length > 0 ? ( <ul> {houses.map((house) => ( <li key={house.id}> <h2>{house.name}</h2> <p>Kategori: {categories.find(cat => cat.id === house.category)?.name}</p> <p>Harga: Rp {house.price}</p> <p>Deskripsi: {house.description}</p> </li> ))} </ul> ) : ( <p>Belum ada data rumah terbaru.</p> )} <h1>Testimoni Penyewa</h1> {testimonials.length > 0 ? ( <ul> {testimonials.map((testimonial) => ( <li key={testimonial.id}> <p>{testimonial.message} - <strong>{testimonial.name}</strong></p> </li> ))} </ul> ) : ( <p>Belum ada testimoni terbaru.</p> )} </div> ); } Penjelasan kode: Pada bagian houses, kita melakukan pengecekan apakah data houses memiliki panjang lebih dari 0. Jika iya, maka kita melakukan mapping pada data tersebut untuk menampilkannya ke layar. Jika tidak, kita menampilkan pesan "Belum ada data rumah terbaru."Hal yang sama dilakukan pada bagian testimonials. Jika ada data, kita menampilkannya; jika tidak, kita memberikan pesan "Belum ada testimoni terbaru." Cara Membuat Component Baru Terpisah untuk Menerima Data dari Halaman Lain Pada proyek Next.js, kita bisa membuat komponen terpisah untuk memudahkan pengelolaan dan modularisasi aplikasi. Komponen ini dapat menerima data yang dilempar dari halaman lain dengan menggunakan props. Props adalah mekanisme di React dan Next.js untuk mengirimkan data dari satu komponen ke komponen lainnya. Berikut adalah langkah-langkah lengkap untuk membuat komponen baru dan menerima data dari halaman lain. Langkah pertama: Buat komponen baru yang akan menerima data. Misalnya, buat komponen HouseList di dalam folder components. // components/HouseList.js export default function HouseList({ houses, categories }) { return ( <div> <h2>Daftar Rumah</h2> {houses.length > 0 ? ( <ul> {houses.map((house) => ( <li key={house.id}> <h3>{house.name}</h3> <p>Kategori: {categories.find(cat => cat.id === house.category)?.name}</p> <p>Harga: Rp {house.price}</p> <p>Deskripsi: {house.description}</p> </li> ))} </ul> ) : ( <p>Belum ada data rumah terbaru.</p> )} </div> ); } Pada komponen HouseList, props houses dan categories akan diterima dari komponen induk dan digunakan untuk melakukan mapping data dan menampilkannya. Jika data houses kosong, maka akan muncul pesan "Belum ada data rumah terbaru." Langkah kedua: Di halaman lain, misalnya halaman Home, kirim data ke komponen HouseList melalui props. // pages/index.js import { houses, categories, testimonials } from '../dummyData'; import HouseList from '../components/HouseList'; export default function Home() { return ( <div> <h1>Website Sewa Rumah</h1> {/* Kirim data houses dan categories ke komponen HouseList */} <HouseList houses={houses} categories={categories} /> <h2>Testimoni Penyewa</h2> {testimonials.length > 0 ? ( <ul> {testimonials.map((testimonial) => ( <li key={testimonial.id}> <p>{testimonial.message} - <strong>{testimonial.name}</strong></p> </li> ))} </ul> ) : ( <p>Belum ada testimoni terbaru.</p> )} </div> ); } Pada halaman Home, kita mengimpor komponen HouseList dan mengirimkan data houses dan categories ke dalam komponen tersebut menggunakan props. Dengan cara ini, komponen HouseList akan menerima data yang dilempar dan menampilkannya sesuai dengan logika yang sudah ditentukan. Penjelasan tambahan: Komponen HouseList bersifat reusable karena dapat menerima data yang berbeda dari berbagai halaman lain jika diperlukan.Data dikirimkan menggunakan props yang merupakan metode standar di React untuk mengirim informasi dari komponen induk ke komponen anak. Ilmu Penting Lain yang Perlu Dipelajari Selanjutnya Setelah mempelajari cara membangun website menggunakan Next.js dan mengelola data dengan baik, ada beberapa ilmu penting lainnya yang bisa membantu meningkatkan kemampuan pengembangan web Anda. Ilmu-ilmu ini sangat berguna untuk mempersiapkan Anda menjadi developer yang lebih mahir dalam membangun aplikasi yang kompleks dan skalabel. Semua topik berikut tersedia di Buildwithangga sebagai bagian dari berbagai kursus yang dapat diakses dengan mudah. 1. React State Management (Redux atau Zustand) Mengelola state dalam aplikasi yang semakin besar bisa menjadi tantangan. Menggunakan alat seperti Redux atau Zustand akan membantu Anda mengelola state secara lebih efisien. Di Buildwithangga, Anda bisa belajar cara menggunakan Redux atau Zustand untuk membangun aplikasi dengan alur data yang lebih teratur dan mudah dipelihara. 2. API Integration dan Authentication Setelah berhasil membangun website yang bisa menampilkan data, penting untuk belajar bagaimana mengintegrasikan API eksternal untuk mengambil data dari server. Selain itu, ilmu tentang autentikasi menggunakan JWT atau OAuth sangat penting untuk menjaga keamanan aplikasi web. Buildwithangga menyediakan kursus yang mengajarkan cara menghubungkan website dengan API dan menerapkan autentikasi yang aman. 3. Deployment dan Optimisasi Website Membuat aplikasi lokal adalah langkah pertama, tetapi memahami cara meng-deploy aplikasi ke server seperti Vercel atau Netlify adalah langkah berikutnya yang penting. Anda juga perlu belajar cara mengoptimalkan performa website agar lebih cepat diakses oleh pengguna. Di Buildwithangga, Anda bisa menemukan panduan lengkap tentang deployment serta teknik optimisasi seperti image lazy loading, caching, dan server-side rendering. 4. TypeScript Jika Anda ingin membangun aplikasi yang lebih skalabel dan mudah di-maintain, TypeScript adalah teknologi yang harus dipelajari. TypeScript memberikan tipedata yang kuat di dalam JavaScript, sehingga mengurangi kesalahan pada saat pengembangan. Buildwithangga menyediakan kursus yang akan membantu Anda memahami bagaimana TypeScript bisa diintegrasikan dengan Next.js untuk membangun aplikasi yang lebih solid. 5. Responsive Design dan Tailwind CSS Untuk membangun website yang tampilannya menarik di berbagai perangkat, mempelajari responsive design dan alat seperti Tailwind CSS sangat penting. Dengan menggunakan Tailwind CSS, Anda bisa mempercepat pengembangan antarmuka yang responsif tanpa perlu menulis CSS dari awal. Di Buildwithangga, Anda dapat belajar cara menerapkan Tailwind CSS dalam proyek Next.js untuk membuat desain yang modern dan responsif. Ilmu-ilmu di atas akan memperluas wawasan dan keterampilan Anda sebagai seorang developer. Dengan belajar dari mentor berpengalaman di Buildwithangga, Anda juga akan mendapatkan akses ke bonus konsultasi, diskusi dengan sesama siswa, serta roadmap belajar yang terstruktur untuk membantu Anda lebih siap menghadapi tantangan di dunia kerja.

Kelas Tutorial Next JS 14 Pemula: Belajar Component dan Manfaat Utamanya di BuildWithAngga

Tutorial Next JS 14 Pemula: Belajar Component dan Manfaat Utamanya

Di era digital seperti sekarang, membangun website modern adalah langkah penting bagi perusahaan yang ingin meningkatkan bisnis mereka secara online. Sebuah website tidak hanya berfungsi sebagai wajah perusahaan di dunia digital, tetapi juga sebagai platform interaksi antara perusahaan dan pelanggannya. Dengan website yang modern dan responsif, perusahaan dapat menjangkau lebih banyak audiens, meningkatkan kepercayaan pelanggan, dan memperkuat branding mereka. Selain itu, website yang baik juga dapat mendukung strategi pemasaran, seperti SEO dan media sosial, yang pada akhirnya membantu meningkatkan penjualan dan profit perusahaan. Oleh karena itu, penting bagi perusahaan untuk terus belajar dan mengikuti perkembangan teknologi agar bisa memaksimalkan potensi website mereka dalam menjalankan bisnis secara online. Mengapa Menggunakan Next.js untuk Website Modern Salah satu framework yang banyak digunakan oleh developer untuk membangun website modern adalah Next.js. Framework ini sangat populer karena fleksibilitasnya yang memungkinkan penggunaannya baik untuk frontend maupun backend. Dengan Next.js, perusahaan dapat membangun aplikasi web yang cepat, efisien, dan SEO-friendly, sehingga dapat meningkatkan performa website dan pengalaman pengguna. Selain itu, Next.js juga mendukung rendering server-side dan static site generation, yang membuatnya sangat cocok untuk berbagai jenis proyek web development. Fleksibilitas inilah yang menjadikan Next.js pilihan tepat untuk perusahaan yang ingin mencoba teknologi terbaru dan menghadirkan website modern yang handal untuk bisnis mereka. Fitur Component dalam Next.js untuk Mempercepat Development Next.js memiliki fitur yang sangat membantu dalam mempercepat proses development, yaitu component. Component dalam Next.js memungkinkan developer untuk memecah tampilan website menjadi bagian-bagian kecil yang terpisah namun saling terhubung. Setiap component ini berfungsi secara independen, yang artinya bisa digunakan kembali di berbagai bagian lain dari aplikasi. Dengan memanfaatkan fitur ini, proses development menjadi jauh lebih efisien karena developer tidak perlu menulis ulang kode yang sama. Selain itu, component juga mempermudah proses maintenance website. Ketika ada perubahan yang perlu dilakukan, developer hanya perlu memperbarui component tertentu tanpa harus memodifikasi keseluruhan aplikasi. Inilah yang membuat component menjadi salah satu fitur andalan di Next.js untuk membangun website modern. Apa Itu Component-Based Architecture dan Jenis Component dalam Next.js Component-based architecture adalah pendekatan dalam pengembangan aplikasi web yang mengorganisir aplikasi menjadi potongan-potongan kecil yang disebut component. Setiap component memiliki fungsi spesifik dan dapat digunakan kembali di berbagai bagian aplikasi. Pendekatan ini membuat kode lebih mudah dipahami, dipelihara, dan dikembangkan dalam jangka panjang. Di Next.js, terdapat beberapa jenis component yang sering digunakan, antara lain: Functional Components: Ini adalah jenis component yang paling umum dalam Next.js. Component ini hanya menerima props dan mengembalikan tampilan (UI). Biasanya digunakan untuk tampilan statis atau elemen yang tidak membutuhkan banyak logika kompleks.Stateful Components: Component yang memiliki internal state, biasanya digunakan ketika aplikasi membutuhkan interaksi dinamis, seperti form input atau perubahan data secara real-time.Presentational Components: Digunakan khusus untuk merender tampilan tanpa memiliki logika bisnis yang kompleks. Presentational components fokus pada bagaimana tampilan muncul kepada pengguna.Container Components: Component yang menangani logika bisnis dan mengelola state dari aplikasi. Biasanya, container components bekerja sama dengan presentational components untuk memisahkan logika dan tampilan. Developer perlu menggunakan component berdasarkan kebutuhan aplikasi. Misalnya, jika hanya membutuhkan tampilan sederhana, maka functional components bisa digunakan. Namun, jika ada interaksi yang lebih kompleks atau pengelolaan data, stateful dan container components menjadi pilihan yang tepat. Dengan memanfaatkan berbagai jenis component ini, developer dapat membangun aplikasi web yang lebih terstruktur, efisien, dan mudah di-maintain. Membuat Project Next.js Toko Sepatu Online Terbaru dengan npm Pada tutorial ini, kita akan membahas bagaimana cara membuat project Next.js terbaru untuk toko sepatu online. Berikut adalah langkah-langkahnya beserta contoh kode yang lengkap. Install Next.js dengan npm Untuk memulai, pastikan npm sudah terpasang di komputer Anda. Setelah itu, buka terminal dan jalankan perintah berikut untuk membuat project Next.js baru: npx create-next-app@latest toko-sepatu-online Perintah ini akan membuat folder bernama toko-sepatu-online dan menginstal semua dependency yang diperlukan untuk memulai project Next.js. Menjalankan Project Next.js Setelah proses instalasi selesai, masuk ke direktori project yang baru saja dibuat: cd toko-sepatu-online Jalankan project Next.js untuk melihat apakah semuanya berjalan dengan baik: npm run dev Kunjungi http://localhost:3000 di browser Anda, dan Anda akan melihat halaman default Next.js. Struktur Project Berikut adalah struktur dasar project yang baru saja dibuat: toko-sepatu-online/ ├── node_modules/ ├── public/ ├── src/ │ ├── pages/ │ └── styles/ ├── .gitignore ├── package.json ├── README.md └── next.config.js Membuat Halaman Home untuk Toko Sepatu Buka file src/pages/index.js dan modifikasi untuk membuat halaman home bagi toko sepatu online Anda: import Head from 'next/head'; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <header> <h1>Selamat Datang di Toko Sepatu Online</h1> <p>Koleksi sepatu terbaru untuk gaya dan kenyamanan Anda</p> </header> </div> ); } Menambahkan Daftar Produk Sepatu Untuk menampilkan daftar sepatu, buat array data produk sepatu di dalam halaman index.js. Kemudian, gunakan fungsi map untuk menampilkan daftar produk tersebut. const products = [ { id: 1, name: 'Sepatu Running', price: 500000 }, { id: 2, name: 'Sepatu Basket', price: 600000 }, { id: 3, name: 'Sepatu Casual', price: 400000 } ]; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <header> <h1>Selamat Datang di Toko Sepatu Online</h1> <p>Koleksi sepatu terbaru untuk gaya dan kenyamanan Anda</p> </header> <section> <h2>Produk Kami</h2> <ul> {products.map((product) => ( <li key={product.id}> <h3>{product.name}</h3> <p>Harga: Rp {product.price}</p> </li> ))} </ul> </section> </div> ); } Menambahkan Style pada Halaman Untuk memberikan tampilan yang lebih baik, tambahkan CSS ke halaman Anda. Buka file src/styles/globals.css dan tambahkan gaya berikut: body { font-family: Arial, sans-serif; margin: 0; padding: 0; box-sizing: border-box; } header { background-color: #f8f9fa; padding: 20px; text-align: center; } h1 { color: #333; } section { padding: 20px; } ul { list-style-type: none; padding: 0; } li { border-bottom: 1px solid #ddd; padding: 10px 0; } Setelah itu, buka kembali halaman di browser Anda. Sekarang tampilan toko sepatu online Anda terlihat lebih rapi dan profesional. Menambahkan Produk Baru Untuk menambahkan produk baru, Anda hanya perlu menambahkannya ke dalam array products di file index.js: const products = [ { id: 1, name: 'Sepatu Running', price: 500000 }, { id: 2, name: 'Sepatu Basket', price: 600000 }, { id: 3, name: 'Sepatu Casual', price: 400000 }, { id: 4, name: 'Sepatu Formal', price: 700000 } ]; Produk baru tersebut akan otomatis muncul di halaman produk tanpa perlu perubahan besar pada kode lainnya. Membuat Beberapa Komponen Utama pada Website Sepatu Online Dalam Next.js, kita bisa memanfaatkan fitur component untuk memecah website menjadi bagian-bagian kecil yang lebih mudah diatur dan dipelihara. Berikut adalah cara membuat beberapa komponen utama untuk website sepatu online beserta contoh koding lengkap. Membuat Komponen Header Komponen pertama yang akan kita buat adalah Header, yang akan menampilkan judul dan deskripsi singkat tentang toko sepatu online. Buat file Header.js di dalam folder src/components. import React from 'react'; const Header = () => { return ( <header> <h1>Toko Sepatu Online</h1> <p>Koleksi sepatu terbaru dengan harga terjangkau</p> </header> ); }; export default Header; Setelah itu, import komponen Header ke dalam halaman utama src/pages/index.js. import Head from 'next/head'; import Header from '../components/Header'; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> {/* Konten lainnya */} </div> ); } Membuat Komponen Produk Selanjutnya, kita buat komponen Product untuk menampilkan informasi setiap produk. Buat file Product.js di dalam folder src/components. import React from 'react'; const Product = ({ name, price }) => { return ( <div> <h3>{name}</h3> <p>Harga: Rp {price}</p> </div> ); }; export default Product; Kemudian, kita gunakan komponen Product ini di halaman utama untuk menampilkan daftar produk. Kembali ke src/pages/index.js dan tambahkan produk ke dalam halaman: import Head from 'next/head'; import Header from '../components/Header'; import Product from '../components/Product'; export default function Home() { const products = [ { id: 1, name: 'Sepatu Running', price: 500000 }, { id: 2, name: 'Sepatu Basket', price: 600000 }, { id: 3, name: 'Sepatu Casual', price: 400000 } ]; return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> <section> <h2>Daftar Produk</h2> <div> {products.map((product) => ( <Product key={product.id} name={product.name} price={product.price} /> ))} </div> </section> </div> ); } Membuat Komponen Footer Untuk melengkapi website, kita buat komponen Footer yang akan berisi informasi singkat tentang toko. Buat file Footer.js di dalam folder src/components. import React from 'react'; const Footer = () => { return ( <footer> <p>© 2024 Toko Sepatu Online. All Rights Reserved.</p> </footer> ); }; export default Footer; Sekarang, tambahkan komponen Footer ke dalam halaman utama index.js agar muncul di bagian bawah halaman. import Head from 'next/head'; import Header from '../components/Header'; import Product from '../components/Product'; import Footer from '../components/Footer'; export default function Home() { const products = [ { id: 1, name: 'Sepatu Running', price: 500000 }, { id: 2, name: 'Sepatu Basket', price: 600000 }, { id: 3, name: 'Sepatu Casual', price: 400000 } ]; return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> <section> <h2>Daftar Produk</h2> <div> {products.map((product) => ( <Product key={product.id} name={product.name} price={product.price} /> ))} </div> </section> <Footer /> </div> ); } Menambahkan Style untuk Komponen Buat tampilan website lebih menarik dengan menambahkan style di file src/styles/globals.css. Berikut adalah contoh CSS yang bisa digunakan: body { font-family: Arial, sans-serif; margin: 0; padding: 0; box-sizing: border-box; } header { background-color: #f8f9fa; padding: 20px; text-align: center; } footer { background-color: #343a40; color: #fff; text-align: center; padding: 10px 0; position: absolute; bottom: 0; width: 100%; } section { padding: 20px; } h1 { color: #333; } h3 { color: #007bff; } p { margin: 0; } Menggunakan Komponen secara Efisien Dengan menggunakan komponen, website sepatu online Anda kini lebih terstruktur dan mudah untuk dikembangkan. Komponen Header, Product, dan Footer bisa digunakan di berbagai halaman, sehingga tidak perlu menulis ulang kode di setiap halaman. Ini tidak hanya mempercepat proses development, tetapi juga memudahkan proses maintenance di masa depan. Komponen memungkinkan Anda untuk fokus pada setiap bagian secara terpisah dan membuat website menjadi lebih modular dan scalable. Membuat Data Dummy pada Website Toko Sepatu dan Mengirimkan Data ke Component di Halaman Lain Dalam membangun website dengan Next.js, salah satu kebutuhan umum adalah membuat data dummy dan mengirimkan data tersebut dari satu halaman ke halaman lainnya. Berikut adalah langkah-langkah lengkap beserta contoh koding untuk membuat data dummy dan meneruskannya antar halaman di website toko sepatu. Membuat Data Dummy Produk Sepatu Pertama, buat data dummy untuk produk sepatu yang bisa diakses dari berbagai halaman. Buat file baru bernama products.js di dalam folder src/data. export const products = [ { id: 1, name: 'Sepatu Running', price: 500000, description: 'Sepatu untuk olahraga lari.' }, { id: 2, name: 'Sepatu Basket', price: 600000, description: 'Sepatu untuk bermain basket.' }, { id: 3, name: 'Sepatu Casual', price: 400000, description: 'Sepatu santai untuk sehari-hari.' }, { id: 4, name: 'Sepatu Formal', price: 700000, description: 'Sepatu formal untuk acara resmi.' } ]; Data ini akan digunakan untuk menampilkan daftar produk di halaman toko sepatu serta diteruskan ke halaman detail produk. Menampilkan Daftar Produk di Halaman Utama Sekarang kita tampilkan data produk di halaman utama. Buka file src/pages/index.js dan impor data dari file products.js, lalu tampilkan daftar produk menggunakan component Product. import Head from 'next/head'; import Header from '../components/Header'; import Product from '../components/Product'; import { products } from '../data/products'; import Link from 'next/link'; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> <section> <h2>Daftar Produk</h2> <div> {products.map((product) => ( <div key={product.id}> <Product name={product.name} price={product.price} /> <Link href={`/product/${product.id}`}> <a>Lihat Detail</a> </Link> </div> ))} </div> </section> </div> ); } Pada kode di atas, setiap produk ditampilkan menggunakan component Product, dan setiap produk juga memiliki link yang mengarahkan pengguna ke halaman detail produk menggunakan Link dari Next.js. Membuat Halaman Detail Produk Untuk menampilkan detail produk, buat halaman dinamis menggunakan routing berbasis file di Next.js. Buat folder product di dalam src/pages, lalu buat file [id].js untuk menangani routing dinamis berdasarkan id produk. import { products } from '../../data/products'; import { useRouter } from 'next/router'; import Head from 'next/head'; const ProductDetail = () => { const router = useRouter(); const { id } = router.query; const product = products.find((p) => p.id === parseInt(id)); if (!product) { return <p>Produk tidak ditemukan</p>; } return ( <div> <Head> <title>{product.name} - Detail Produk</title> <meta name="description" content={`Detail produk untuk ${product.name}`} /> </Head> <h1>{product.name}</h1> <p>Harga: Rp {product.price}</p> <p>{product.description}</p> </div> ); }; export default ProductDetail; Pada halaman ini, id produk diambil dari URL menggunakan useRouter() dari Next.js. Produk yang sesuai dengan id tersebut kemudian dicari dari data dummy dan ditampilkan detailnya. Jika produk tidak ditemukan, akan muncul pesan "Produk tidak ditemukan". Menghubungkan Halaman Utama dengan Halaman Detail Kembali ke halaman utama, kita telah menambahkan link yang mengarahkan ke halaman detail produk dengan URL /product/[id]. Ketika pengguna mengklik link "Lihat Detail" pada suatu produk, mereka akan diarahkan ke halaman ProductDetail yang menampilkan informasi lengkap produk tersebut. Misalnya, jika pengguna mengklik produk dengan id 1, mereka akan diarahkan ke URL /product/1, dan halaman detail akan menampilkan nama, harga, dan deskripsi produk tersebut. Menambahkan Style untuk Halaman Detail Agar tampilan lebih menarik, tambahkan style untuk halaman detail produk di file src/styles/globals.css. h1 { color: #007bff; margin-top: 20px; } p { font-size: 18px; } a { color: #007bff; text-decoration: none; } a:hover { text-decoration: underline; } Mengatur Types TypeScript pada Component di Next.js Dalam project Next.js yang menggunakan TypeScript, mengatur types pada setiap component sangat penting untuk memastikan data yang diterima atau dikirim lebih akurat dan aman. Berikut adalah langkah-langkah lengkap beserta contoh koding untuk mengatur types TypeScript pada component agar data yang diterima atau dikirim sesuai dengan yang diharapkan. Mengaktifkan TypeScript pada Project Next.js Jika project Next.js Anda belum menggunakan TypeScript, Anda bisa mengaktifkannya dengan menjalankan perintah berikut: touch tsconfig.json npm install --save-dev typescript @types/react @types/node Setelah itu, jalankan project Next.js Anda, dan Next.js akan otomatis mengonversi file-file ke dalam format TypeScript. Menyiapkan Data Dummy dengan TypeScript Langkah pertama adalah membuat type untuk data dummy. Buat file baru bernama types.ts di dalam folder src untuk mendefinisikan type yang digunakan. Misalnya, kita ingin mendefinisikan type untuk produk sepatu: export interface Product { id: number; name: string; price: number; description: string; } Type Product ini memiliki empat properti: id, name, price, dan description, yang semuanya wajib ada ketika produk digunakan. Membuat Data Dummy dengan Type Setelah mendefinisikan type, kita dapat menggunakannya dalam file products.ts yang berisi data dummy. Buka file src/data/products.ts dan gunakan type yang sudah didefinisikan: import { Product } from '../types'; export const products: Product[] = [ { id: 1, name: 'Sepatu Running', price: 500000, description: 'Sepatu untuk olahraga lari.' }, { id: 2, name: 'Sepatu Basket', price: 600000, description: 'Sepatu untuk bermain basket.' }, { id: 3, name: 'Sepatu Casual', price: 400000, description: 'Sepatu santai untuk sehari-hari.' }, { id: 4, name: 'Sepatu Formal', price: 700000, description: 'Sepatu formal untuk acara resmi.' } ]; Di sini, kita menggunakan Product[] untuk mendefinisikan bahwa variabel products adalah array dari objek Product. Mengatur Type pada Komponen Product Sekarang kita akan membuat komponen Product dan menetapkan type untuk data yang diterima oleh komponen tersebut. Buka file src/components/Product.tsx dan buat komponen dengan TypeScript. import React from 'react'; import { Product } from '../types'; interface ProductProps { name: string; price: number; } const ProductComponent: React.FC<ProductProps> = ({ name, price }) => { return ( <div> <h3>{name}</h3> <p>Harga: Rp {price}</p> </div> ); }; export default ProductComponent; Di sini, kita membuat interface ProductProps untuk mendefinisikan bahwa ProductComponent menerima dua props: name dan price, yang keduanya bertipe string dan number. Menggunakan Komponen dengan Type yang Tepat Sekarang, kita akan menggunakan ProductComponent di halaman utama. Buka file src/pages/index.tsx dan impor data serta component: import Head from 'next/head'; import Header from '../components/Header'; import ProductComponent from '../components/Product'; import { products } from '../data/products'; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> <section> <h2>Daftar Produk</h2> <div> {products.map((product) => ( <ProductComponent key={product.id} name={product.name} price={product.price} /> ))} </div> </section> </div> ); } Pada bagian ini, kita memastikan bahwa setiap produk yang dilemparkan ke ProductComponent memiliki data dengan tipe yang sesuai (name: string dan price: number). Menambahkan Type untuk Routing Dinamis Selain mengatur types pada komponen, kita juga bisa mengatur types untuk halaman dengan routing dinamis. Buka file src/pages/product/[id].tsx dan tambahkan type untuk menangani produk: import { useRouter } from 'next/router'; import { products } from '../../data/products'; import { Product } from '../../types'; const ProductDetail: React.FC = () => { const router = useRouter(); const { id } = router.query; const product: Product | undefined = products.find((p) => p.id === Number(id)); if (!product) { return <p>Produk tidak ditemukan</p>; } return ( <div> <h1>{product.name}</h1> <p>Harga: Rp {product.price}</p> <p>{product.description}</p> </div> ); }; export default ProductDetail; Di sini, kita memastikan bahwa data product yang ditemukan sesuai dengan type Product. Jika product tidak ditemukan, halaman akan menampilkan pesan error. Menerapkan State Management pada Component agar Data dan Tampilan Dinamis Dalam pengembangan aplikasi Next.js, state management sangat penting untuk membuat komponen lebih dinamis. Dengan state, kita bisa mengatur data yang berubah secara real-time, seperti interaksi pengguna atau perubahan nilai dari input. Berikut adalah langkah-langkah lengkap untuk menerapkan state management pada sebuah komponen dengan contoh koding yang rinci. Membuat State dengan useState Pertama, kita akan membuat komponen sederhana yang menggunakan useState untuk mengelola state di dalamnya. Misalnya, kita akan membuat komponen yang menampilkan daftar sepatu dan memungkinkan pengguna untuk menambah produk sepatu ke dalam daftar favorit. Buat komponen baru bernama ProductList.tsx di dalam folder src/components: import React, { useState } from 'react'; const ProductList = () => { const [favorites, setFavorites] = useState<string[]>([]); const products = ['Sepatu Running', 'Sepatu Basket', 'Sepatu Casual', 'Sepatu Formal']; const addFavorite = (product: string) => { if (!favorites.includes(product)) { setFavorites([...favorites, product]); } }; return ( <div> <h2>Daftar Produk</h2> <ul> {products.map((product) => ( <li key={product}> {product} <button onClick={() => addFavorite(product)}>Tambah ke Favorit</button> </li> ))} </ul> <h3>Produk Favorit</h3> {favorites.length > 0 ? ( <ul> {favorites.map((favorite) => ( <li key={favorite}>{favorite}</li> ))} </ul> ) : ( <p>Belum ada produk favorit</p> )} </div> ); }; export default ProductList; Pada contoh di atas, kita menggunakan useState untuk menyimpan daftar produk favorit di state favorites. Komponen ini memiliki daftar produk sepatu, dan pengguna bisa menambahkan produk ke daftar favorit dengan mengklik tombol "Tambah ke Favorit". Setiap kali produk ditambahkan, state favorites diperbarui, dan daftar favorit ditampilkan secara dinamis di bawah daftar produk. Menampilkan Komponen di Halaman Utama Selanjutnya, kita akan menampilkan komponen ProductList di halaman utama. Buka file src/pages/index.tsx dan tambahkan ProductList ke dalamnya: import Head from 'next/head'; import Header from '../components/Header'; import ProductList from '../components/ProductList'; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> <ProductList /> </div> ); } Sekarang, komponen ProductList akan muncul di halaman utama. Pengguna dapat menambah produk ke daftar favorit, dan setiap produk yang dipilih akan ditampilkan secara dinamis di bagian "Produk Favorit". Mengelola State dengan Input Pengguna Untuk memperlihatkan lebih banyak penggunaan state, kita akan menambahkan input yang memungkinkan pengguna untuk menambahkan produk baru ke daftar produk. Kembali ke file ProductList.tsx dan tambahkan input untuk menambah produk: import React, { useState } from 'react'; const ProductList = () => { const [favorites, setFavorites] = useState<string[]>([]); const [products, setProducts] = useState<string[]>(['Sepatu Running', 'Sepatu Basket', 'Sepatu Casual', 'Sepatu Formal']); const [newProduct, setNewProduct] = useState<string>(''); const addFavorite = (product: string) => { if (!favorites.includes(product)) { setFavorites([...favorites, product]); } }; const addProduct = () => { if (newProduct && !products.includes(newProduct)) { setProducts([...products, newProduct]); setNewProduct(''); } }; return ( <div> <h2>Daftar Produk</h2> <ul> {products.map((product) => ( <li key={product}> {product} <button onClick={() => addFavorite(product)}>Tambah ke Favorit</button> </li> ))} </ul> <h3>Tambah Produk Baru</h3> <input type="text" value={newProduct} onChange={(e) => setNewProduct(e.target.value)} placeholder="Nama produk baru" /> <button onClick={addProduct}>Tambah Produk</button> <h3>Produk Favorit</h3> {favorites.length > 0 ? ( <ul> {favorites.map((favorite) => ( <li key={favorite}>{favorite}</li> ))} </ul> ) : ( <p>Belum ada produk favorit</p> )} </div> ); }; export default ProductList; Pada kode di atas, kita menambahkan state baru newProduct untuk menyimpan input dari pengguna. Ketika pengguna mengetikkan nama produk baru, state newProduct akan diperbarui, dan ketika tombol "Tambah Produk" diklik, produk baru akan ditambahkan ke daftar produk menggunakan setProducts. Daftar produk diperbarui secara dinamis, dan pengguna juga dapat menambahkan produk baru ke daftar favorit. Menyimpan State di Local Storage (Opsional) Untuk mempertahankan state meskipun halaman di-refresh, Anda bisa menggunakan local storage. Berikut adalah cara menerapkan penyimpanan data menggunakan local storage pada state produk favorit: Tambahkan efek samping untuk menyimpan dan mengambil data dari local storage menggunakan useEffect dari React: import React, { useState, useEffect } from 'react'; const ProductList = () => { const [favorites, setFavorites] = useState<string[]>([]); const [products, setProducts] = useState<string[]>(['Sepatu Running', 'Sepatu Basket', 'Sepatu Casual', 'Sepatu Formal']); const [newProduct, setNewProduct] = useState<string>(''); useEffect(() => { const savedFavorites = localStorage.getItem('favorites'); if (savedFavorites) { setFavorites(JSON.parse(savedFavorites)); } }, []); useEffect(() => { localStorage.setItem('favorites', JSON.stringify(favorites)); }, [favorites]); const addFavorite = (product: string) => { if (!favorites.includes(product)) { setFavorites([...favorites, product]); } }; const addProduct = () => { if (newProduct && !products.includes(newProduct)) { setProducts([...products, newProduct]); setNewProduct(''); } }; return ( <div> <h2>Daftar Produk</h2> <ul> {products.map((product) => ( <li key={product}> {product} <button onClick={() => addFavorite(product)}>Tambah ke Favorit</button> </li> ))} </ul> <h3>Tambah Produk Baru</h3> <input type="text" value={newProduct} onChange={(e) => setNewProduct(e.target.value)} placeholder="Nama produk baru" /> <button onClick={addProduct}>Tambah Produk</button> <h3>Produk Favorit</h3> {favorites.length > 0 ? ( <ul> {favorites.map((favorite) => ( <li key={favorite}>{favorite}</li> ))} </ul> ) : ( <p>Belum ada produk favorit</p> )} </div> ); }; export default ProductList; Pada contoh ini, state favorites disimpan ke dalam local storage setiap kali produk baru ditambahkan ke dalam daftar favorit, dan saat halaman dimuat kembali, data favorit diambil dari local storage. Menerapkan Conditional Rendering pada Component di Proyek Toko Sepatu Online Dalam sebuah aplikasi, terkadang kita perlu menampilkan elemen atau konten yang berbeda berdasarkan kondisi tertentu. Pada proyek toko sepatu online, kita bisa menggunakan conditional rendering untuk mengontrol tampilan berdasarkan kondisi seperti ketersediaan produk, status login pengguna, atau kategori produk yang dipilih. Berikut adalah langkah-langkah untuk menerapkan conditional rendering pada sebuah component dengan contoh kode lengkap. Membuat Komponen Produk dengan Ketersediaan Stok Kita akan membuat komponen ProductList yang menampilkan daftar sepatu. Sepatu yang stoknya habis akan ditampilkan dengan pesan khusus, sementara sepatu yang tersedia akan menampilkan tombol "Tambah ke Keranjang". Buat file ProductList.tsx di dalam folder src/components: import React from 'react'; interface Product { id: number; name: string; price: number; isAvailable: boolean; } const ProductList: React.FC = () => { const products: Product[] = [ { id: 1, name: 'Sepatu Running', price: 500000, isAvailable: true }, { id: 2, name: 'Sepatu Basket', price: 600000, isAvailable: false }, { id: 3, name: 'Sepatu Casual', price: 400000, isAvailable: true }, { id: 4, name: 'Sepatu Formal', price: 700000, isAvailable: false } ]; return ( <div> <h2>Daftar Produk</h2> <ul> {products.map((product) => ( <li key={product.id}> <h3>{product.name}</h3> <p>Harga: Rp {product.price}</p> {product.isAvailable ? ( <button>Tambah ke Keranjang</button> ) : ( <p style={{ color: 'red' }}>Stok Habis</p> )} </li> ))} </ul> </div> ); }; export default ProductList; Pada contoh di atas, kita menggunakan conditional rendering untuk menampilkan pesan "Stok Habis" jika isAvailable bernilai false. Jika isAvailable bernilai true, maka akan menampilkan tombol "Tambah ke Keranjang". Ini adalah cara dasar untuk menerapkan conditional rendering di dalam komponen berdasarkan kondisi stok produk. Menampilkan Komponen di Halaman Utama Untuk menampilkan komponen ini di halaman utama, buka file src/pages/index.tsx dan tambahkan komponen ProductList: import Head from 'next/head'; import Header from '../components/Header'; import ProductList from '../components/ProductList'; export default function Home() { return ( <div> <Head> <title>Toko Sepatu Online</title> <meta name="description" content="Belanja sepatu online dengan koleksi terbaru" /> </Head> <Header /> <ProductList /> </div> ); } Sekarang, ketika Anda membuka halaman utama, daftar produk akan ditampilkan dengan pesan khusus jika stok habis. Conditional Rendering Berdasarkan Kategori Produk Selanjutnya, kita akan menerapkan conditional rendering berdasarkan kategori produk yang dipilih oleh pengguna. Buat sebuah state untuk menyimpan kategori yang dipilih, dan tampilkan produk berdasarkan kategori tersebut. Modifikasi file ProductList.tsx untuk menambahkan fitur ini: import React, { useState } from 'react'; interface Product { id: number; name: string; price: number; category: string; isAvailable: boolean; } const ProductList: React.FC = () => { const [selectedCategory, setSelectedCategory] = useState<string>('All'); const products: Product[] = [ { id: 1, name: 'Sepatu Running', price: 500000, category: 'Olahraga', isAvailable: true }, { id: 2, name: 'Sepatu Basket', price: 600000, category: 'Olahraga', isAvailable: false }, { id: 3, name: 'Sepatu Casual', price: 400000, category: 'Casual', isAvailable: true }, { id: 4, name: 'Sepatu Formal', price: 700000, category: 'Formal', isAvailable: false } ]; const filteredProducts = selectedCategory === 'All' ? products : products.filter((product) => product.category === selectedCategory); return ( <div> <h2>Daftar Produk</h2> <div> <button onClick={() => setSelectedCategory('All')}>Semua</button> <button onClick={() => setSelectedCategory('Olahraga')}>Olahraga</button> <button onClick={() => setSelectedCategory('Casual')}>Casual</button> <button onClick={() => setSelectedCategory('Formal')}>Formal</button> </div> <ul> {filteredProducts.map((product) => ( <li key={product.id}> <h3>{product.name}</h3> <p>Harga: Rp {product.price}</p> {product.isAvailable ? ( <button>Tambah ke Keranjang</button> ) : ( <p style={{ color: 'red' }}>Stok Habis</p> )} </li> ))} </ul> </div> ); }; export default ProductList; Pada contoh ini, kita menambahkan tombol untuk memilih kategori produk (All, Olahraga, Casual, Formal). Berdasarkan kategori yang dipilih, daftar produk akan difilter menggunakan metode filter(). Hasil filter tersebut kemudian ditampilkan dengan conditional rendering yang sama untuk ketersediaan stok. Menyempurnakan Tampilan dengan Conditional Rendering Kita juga bisa menyempurnakan tampilan dengan menambahkan pesan khusus jika tidak ada produk yang sesuai dengan kategori yang dipilih. Modifikasi kode di dalam ProductList.tsx: import React, { useState } from 'react'; interface Product { id: number; name: string; price: number; category: string; isAvailable: boolean; } const ProductList: React.FC = () => { const [selectedCategory, setSelectedCategory] = useState<string>('All'); const products: Product[] = [ { id: 1, name: 'Sepatu Running', price: 500000, category: 'Olahraga', isAvailable: true }, { id: 2, name: 'Sepatu Basket', price: 600000, category: 'Olahraga', isAvailable: false }, { id: 3, name: 'Sepatu Casual', price: 400000, category: 'Casual', isAvailable: true }, { id: 4, name: 'Sepatu Formal', price: 700000, category: 'Formal', isAvailable: false } ]; const filteredProducts = selectedCategory === 'All' ? products : products.filter((product) => product.category === selectedCategory); return ( <div> <h2>Daftar Produk</h2> <div> <button onClick={() => setSelectedCategory('All')}>Semua</button> <button onClick={() => setSelectedCategory('Olahraga')}>Olahraga</button> <button onClick={() => setSelectedCategory('Casual')}>Casual</button> <button onClick={() => setSelectedCategory('Formal')}>Formal</button> </div> {filteredProducts.length > 0 ? ( <ul> {filteredProducts.map((product) => ( <li key={product.id}> <h3>{product.name}</h3> <p>Harga: Rp {product.price}</p> {product.isAvailable ? ( <button>Tambah ke Keranjang</button> ) : ( <p style={{ color: 'red' }}>Stok Habis</p> )} </li> ))} </ul> ) : ( <p>Tidak ada produk untuk kategori {selectedCategory}</p> )} </div> ); }; export default ProductList; Jika kategori yang dipilih tidak memiliki produk, akan muncul pesan "Tidak ada produk untuk kategori [kategori]". Dengan menggunakan conditional rendering, Anda dapat menampilkan elemen atau konten berdasarkan kondisi tertentu. Dalam contoh ini, kita menampilkan pesan khusus untuk stok habis dan memfilter produk berdasarkan kategori yang dipilih. Ini adalah teknik yang sangat bermanfaat untuk membuat tampilan aplikasi lebih dinamis dan interaktif, sesuai dengan kebutuhan pengguna dan data yang ada. 3 Kesalahan Utama Saat Membangun Website Menggunakan Komponen di Next.js App Router Dalam membangun website menggunakan Next.js dan fitur app router, ada beberapa kesalahan umum yang sering dilakukan oleh pengembang. Kesalahan ini dapat menyebabkan aplikasi tidak berjalan secara efisien atau menimbulkan bug yang sulit dilacak. Berikut adalah tiga kesalahan utama beserta solusi dan contoh koding lengkap untuk menghindarinya. 1. Tidak Memisahkan Logika Bisnis dari Komponen UI Kesalahan pertama adalah mencampuradukkan logika bisnis dengan tampilan (UI) dalam satu komponen. Ini membuat komponen menjadi sulit di-maintain dan di-reuse, serta mempersulit debugging di masa depan. Sebaiknya, pisahkan logika bisnis dari komponen UI agar komponen tetap sederhana. Contoh kesalahan: import React, { useState, useEffect } from 'react'; const ProductList = () => { const [products, setProducts] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { // Fetch data langsung di dalam komponen UI fetch('/api/products') .then((res) => res.json()) .then((data) => { setProducts(data); setIsLoading(false); }); }, []); return ( <div> {isLoading ? <p>Loading...</p> : products.map((product) => <p key={product.id}>{product.name}</p>)} </div> ); }; export default ProductList; Solusi: Pindahkan logika fetch data ke dalam fungsi terpisah atau gunakan custom hook. import React, { useState, useEffect } from 'react'; // Custom hook untuk fetching data const useProducts = () => { const [products, setProducts] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { fetch('/api/products') .then((res) => res.json()) .then((data) => { setProducts(data); setIsLoading(false); }); }, []); return { products, isLoading }; }; const ProductList = () => { const { products, isLoading } = useProducts(); return ( <div> {isLoading ? <p>Loading...</p> : products.map((product) => <p key={product.id}>{product.name}</p>)} </div> ); }; export default ProductList; 2. Tidak Menggunakan Key yang Unik saat Mapping Elemen Kesalahan kedua adalah tidak memberikan key yang unik saat melakukan rendering list dengan map(). Ini sering menyebabkan peringatan di console, dan bisa mengakibatkan bug rendering yang tidak terduga. Contoh kesalahan: const ProductList = ({ products }) => { return ( <ul> {products.map((product) => ( <li>{product.name}</li> // Tidak menggunakan key ))} </ul> ); }; Solusi: Pastikan setiap elemen dalam list memiliki key yang unik, misalnya menggunakan id dari data produk. const ProductList = ({ products }) => { return ( <ul> {products.map((product) => ( <li key={product.id}>{product.name}</li> // Menggunakan key yang unik ))} </ul> ); }; 3. Melakukan Fetch Data di Setiap Render Tanpa Mekanisme Caching Kesalahan ketiga adalah melakukan fetch data berulang-ulang setiap kali komponen dirender tanpa caching atau mekanisme pembatasan. Ini akan mengurangi performa aplikasi, terutama jika fetch data dilakukan dari API eksternal. Contoh kesalahan: const ProductList = () => { const [products, setProducts] = useState([]); useEffect(() => { fetch('/api/products') // Fetch data setiap kali komponen dirender .then((res) => res.json()) .then((data) => setProducts(data)); }, []); // Tidak ada caching }; Solusi: Gunakan mekanisme caching seperti useSWR untuk menghindari fetch data berulang kali. import useSWR from 'swr'; const fetcher = (url) => fetch(url).then((res) => res.json()); const ProductList = () => { const { data: products, error } = useSWR('/api/products', fetcher); if (error) return <p>Error loading data</p>; if (!products) return <p>Loading...</p>; return ( <ul> {products.map((product) => ( <li key={product.id}>{product.name}</li> ))} </ul> ); }; export default ProductList; Dengan menggunakan useSWR, data hanya akan di-fetch sekali dan disimpan di cache, sehingga performa aplikasi tetap optimal. Penutup Dengan memahami dan menghindari kesalahan-kesalahan umum dalam membangun website menggunakan komponen di Next.js, kita bisa menciptakan aplikasi yang lebih efisien dan mudah di-maintain. Jika Anda ingin meningkatkan kemampuan coding lebih lanjut dan belajar secara mendalam, Anda bisa belajar bersama mentor expert BuildWithAngga. Selain mendapatkan akses selamanya, Anda juga bisa membangun portfolio berkualitas, konsultasi langsung dengan mentor, dan mendapatkan beragam benefit menarik lainnya yang akan membantu Anda menjadi web developer profesional. Mari bergabung dan raih kesuksesan di dunia web development bersama BuildWithAngga!

Kelas Tutorial Next JS 14 Pemula: Mengatur SEO Pada App Router di BuildWithAngga

Tutorial Next JS 14 Pemula: Mengatur SEO Pada App Router

Next.js adalah framework yang sangat populer di kalangan developer karena memberikan kemudahan dalam membangun aplikasi web modern. Di dalam Next.js, terdapat dua versi routing utama yang dikenal sebagai App Router dan Pages Router. Perbedaan mendasar dari keduanya terletak pada cara mereka mengatur dan mengelola SEO tags seperti title, meta description, dan meta tags lainnya. Pada Pages Router, struktur routing lebih tradisional di mana setiap halaman web diwakili oleh sebuah file di dalam folder pages. SEO diatur melalui file Head yang diimport di setiap file komponen, atau menggunakan next/head. Sedangkan App Router lebih fleksibel dan memberikan kontrol lebih pada developer dalam mengatur SEO. App Router memungkinkan kamu untuk lebih mudah menggunakan fitur-fitur canggih dari React dan Next.js, termasuk optimisasi SEO yang lebih granular dan dinamis. Meskipun keduanya memiliki pendekatan yang berbeda dalam mengelola halaman dan SEO, tujuan akhirnya tetap sama, yaitu memberikan pengalaman yang lebih optimal bagi pengguna dan meningkatkan performa website di mesin pencari. Pentingnya SEO dalam Next.js untuk Meningkatkan Peringkat Website Salah satu keunggulan besar menggunakan Next.js adalah kemampuannya dalam mendukung Server-Side Rendering (SSR), yang sangat membantu dalam meningkatkan SEO (Search Engine Optimization). SEO sangat penting karena dapat membantu website kamu muncul lebih tinggi di hasil pencarian Google dan mesin pencari lainnya, yang pada gilirannya dapat mendatangkan lebih banyak customer atau pengunjung secara online. Dengan SSR, Next.js memungkinkan halaman web untuk dirender di server terlebih dahulu sebelum dikirim ke browser pengguna. Hal ini memastikan bahwa search engine bots dapat mengindeks halaman dengan lebih efektif karena konten sudah siap di server, bukan hanya berupa kode JavaScript yang harus diinterpretasi di browser. Selain itu, kamu bisa memastikan bahwa metadata penting seperti title, description, dan open graph tags sudah tersedia sejak awal, yang akan membantu meningkatkan nilai SEO secara keseluruhan. Jadi, bagi para developer yang ingin membangun website dengan performa SEO yang lebih baik, Next.js adalah pilihan yang sangat kuat karena framework ini memang didesain untuk memberikan performa yang optimal dan pengalaman yang baik bagi pengguna dan search engine bots. Latihan Mengatur SEO pada Proyek Website Jual Mobil Online Pada artikel ini, kita akan berlatih mengatur SEO untuk sebuah proyek website jual mobil online menggunakan Next.js. Ini adalah langkah penting untuk mempersiapkan diri menjadi seorang frontend developer yang matang. Mengatur SEO dengan baik adalah salah satu keterampilan yang sangat berharga dalam dunia web development, terutama karena SEO dapat membantu website kamu lebih mudah ditemukan oleh calon pembeli di mesin pencari seperti Google. Dengan memanfaatkan kemampuan Server-Side Rendering (SSR) di Next.js, kita bisa memastikan bahwa website jual mobil kita dioptimalkan untuk SEO, sehingga mampu mendatangkan lebih banyak traffic organik secara online. Latihan ini akan membekali kamu dengan keterampilan praktis yang bisa langsung diterapkan pada proyek-proyek profesional lainnya, terutama untuk website yang memerlukan pengaturan SEO yang kuat agar dapat bersaing di dunia digital. Cara Menginstall Proyek Next.js 14 App Router Terbaru Sebelum memulai, pastikan kamu sudah menginstal Node.js di komputer kamu. Jika belum, kamu bisa download dan menginstalnya dari Node.js website. Setelah itu, kita akan menggunakan npx untuk membuat proyek Next.js dengan App Router terbaru. Berikut langkah-langkah lengkapnya: Buka terminal atau command prompt di komputer kamu.Jalankan perintah berikut untuk membuat proyek Next.js dengan App Router terbaru: npx create-next-app@latest my-car-shop --use-app-router Setelah perintah ini dijalankan, kamu akan diminta untuk memasukkan beberapa informasi seperti: Nama proyek: Kamu bisa menekan Enter untuk menggunakan nama default atau mengetik nama lain.Apakah kamu ingin menggunakan TypeScript: Pilih 'Yes' atau 'No' tergantung preferensi kamu.Apakah ingin menggunakan ESLint: Pilih 'Yes' jika kamu ingin menambahkan linting pada proyek.Apakah ingin menggunakan Tailwind CSS: Pilih 'Yes' atau 'No' tergantung kebutuhan proyek.Apakah ingin menggunakan src directory: Pilih 'Yes' atau 'No' tergantung struktur folder yang kamu inginkan.Apakah ingin mengkonfigurasi test setup: Pilih 'Yes' jika kamu ingin menambahkan testing.Apakah ingin menggunakan import alias: Pilih 'Yes' jika kamu ingin mengatur alias pada import file. Setelah semua pilihan dijawab, proses instalasi akan berjalan dan proyek Next.js kamu akan siap.Setelah proyek berhasil dibuat, masuk ke folder proyek dengan perintah: cd my-car-shop Untuk menjalankan proyek di server lokal, gunakan perintah berikut: npm run dev Buka browser dan akses proyek kamu di http://localhost:3000. Dengan langkah-langkah ini, kamu sudah berhasil menginstal Next.js 14 dengan App Router terbaru dan siap untuk memulai pengembangan proyek website jual mobil online. Cara Membuat Halaman page.tsx untuk Daftar Mobil dan Detail Mobil dengan Slug di Next.js Setelah berhasil menginstal proyek Next.js 14 dengan App Router, kita akan membuat halaman daftar mobil dan detail mobil menggunakan dummy data. Langkah ini akan menunjukkan cara menggunakan slug untuk mengakses detail setiap mobil. 1. Membuat Halaman Daftar Mobil di Folder cars Pertama, buat folder cars di dalam folder app untuk menyimpan halaman daftar mobil. Di dalam folder ini, kita akan membuat file page.tsx yang akan menampilkan semua mobil dari dummy data. Buat file page.tsx di folder app/cars dan tambahkan kode berikut: // app/cars/page.tsx import Link from 'next/link'; const cars = [ { id: 1, name: 'Toyota Avanza', slug: 'toyota-avanza', price: 150000000 }, { id: 2, name: 'Honda Civic', slug: 'honda-civic', price: 300000000 }, { id: 3, name: 'Suzuki Swift', slug: 'suzuki-swift', price: 200000000 }, ]; const CarsPage = () => { return ( <div> <h1>Daftar Mobil Dijual</h1> <ul> {cars.map((car) => ( <li key={car.id}> <Link href={`/cars/${car.slug}`}> {car.name} - Rp {car.price.toLocaleString()} </Link> </li> ))} </ul> </div> ); }; export default CarsPage; Pada kode di atas, kita membuat array cars yang berisi beberapa dummy data mobil dengan id, name, slug, dan price. Kemudian, kita menggunakan map() untuk menampilkan daftar mobil dan membuat link untuk setiap mobil yang akan menuju ke halaman detail berdasarkan slug. 2. Membuat Halaman Detail Mobil dengan Slug Selanjutnya, kita akan membuat halaman detail mobil yang bisa diakses menggunakan slug. Buat folder [slug] di dalam folder cars, lalu buat file page.tsx di dalam folder tersebut. Berikut adalah kode untuk menampilkan detail mobil berdasarkan slug: // app/cars/[slug]/page.tsx import { useParams } from 'next/navigation'; const cars = [ { id: 1, name: 'Toyota Avanza', slug: 'toyota-avanza', price: 150000000, description: 'Toyota Avanza adalah mobil keluarga yang sangat populer di Indonesia.' }, { id: 2, name: 'Honda Civic', slug: 'honda-civic', price: 300000000, description: 'Honda Civic menawarkan desain sporty dan performa mesin yang tangguh.' }, { id: 3, name: 'Suzuki Swift', slug: 'suzuki-swift', price: 200000000, description: 'Suzuki Swift adalah hatchback dengan desain compact dan efisiensi bahan bakar yang baik.' }, ]; const CarDetailPage = () => { const params = useParams(); const car = cars.find((car) => car.slug === params.slug); if (!car) { return <div>Mobil tidak ditemukan</div>; } return ( <div> <h1>{car.name}</h1> <p>Harga: Rp {car.price.toLocaleString()}</p> <p>{car.description}</p> </div> ); }; export default CarDetailPage; Di halaman ini, kita menggunakan useParams dari next/navigation untuk mengambil slug dari URL dan mencocokkannya dengan dummy data mobil. Jika slug ditemukan, kita akan menampilkan detail mobil, termasuk nama, harga, dan deskripsi. Jika tidak ditemukan, kita akan menampilkan pesan "Mobil tidak ditemukan". Dengan langkah ini, kamu sudah berhasil membuat dua halaman: satu untuk menampilkan daftar mobil, dan satu lagi untuk menampilkan detail mobil berdasarkan slug. Mengimplementasikan generateMetadata untuk Meningkatkan SEO di Halaman Cars dan Detail Car Dalam Next.js, kita dapat menggunakan fungsi generateMetadata untuk meningkatkan SEO dengan menambahkan meta tags seperti title, description, dan keywords secara dinamis. Ini sangat membantu dalam memberikan informasi yang relevan kepada mesin pencari dan dapat meningkatkan peringkat website. 1. Mengimplementasikan generateMetadata di Halaman Cars Untuk meningkatkan SEO di halaman daftar mobil, kita bisa menambahkan metadata seperti title dan description. Berikut adalah cara mengimplementasikan generateMetadata di file page.tsx pada folder cars: // app/cars/page.tsx import Link from 'next/link'; const cars = [ { id: 1, name: 'Toyota Avanza', slug: 'toyota-avanza', price: 150000000 }, { id: 2, name: 'Honda Civic', slug: 'honda-civic', price: 300000000 }, { id: 3, name: 'Suzuki Swift', slug: 'suzuki-swift', price: 200000000 }, ]; // Fungsi generateMetadata untuk meningkatkan SEO export async function generateMetadata() { return { title: 'Daftar Mobil Dijual - Jual Mobil Online', description: 'Temukan berbagai mobil bekas dan baru yang dijual dengan harga terbaik di website kami.', }; } const CarsPage = () => { return ( <div> <h1>Daftar Mobil Dijual</h1> <ul> {cars.map((car) => ( <li key={car.id}> <Link href={`/cars/${car.slug}`}> {car.name} - Rp {car.price.toLocaleString()} </Link> </li> ))} </ul> </div> ); }; export default CarsPage; Pada kode di atas, kita menambahkan fungsi generateMetadata yang mengembalikan objek metadata. title diatur untuk menampilkan judul halaman yang relevan, sedangkan description berisi deskripsi singkat yang dapat membantu mesin pencari memahami konten halaman. 2. Mengimplementasikan generateMetadata di Halaman Detail Mobil dengan Slug Untuk halaman detail mobil, kita bisa mengatur metadata yang dinamis berdasarkan slug mobil. Dengan cara ini, setiap mobil akan memiliki SEO yang unik dan relevan. Berikut adalah cara menambahkan generateMetadata pada file page.tsx di dalam folder [slug]: // app/cars/[slug]/page.tsx import { useParams } from 'next/navigation'; const cars = [ { id: 1, name: 'Toyota Avanza', slug: 'toyota-avanza', price: 150000000, description: 'Toyota Avanza adalah mobil keluarga yang sangat populer di Indonesia.' }, { id: 2, name: 'Honda Civic', slug: 'honda-civic', price: 300000000, description: 'Honda Civic menawarkan desain sporty dan performa mesin yang tangguh.' }, { id: 3, name: 'Suzuki Swift', slug: 'suzuki-swift', price: 200000000, description: 'Suzuki Swift adalah hatchback dengan desain compact dan efisiensi bahan bakar yang baik.' }, ]; // Fungsi generateMetadata untuk setiap mobil berdasarkan slug export async function generateMetadata({ params }) { const car = cars.find((car) => car.slug === params.slug); if (car) { return { title: `${car.name} - Jual Mobil Online`, description: `Beli ${car.name} dengan harga Rp ${car.price.toLocaleString()} hanya di website kami. ${car.description}`, }; } return { title: 'Mobil Tidak Ditemukan', description: 'Mobil yang Anda cari tidak tersedia di website kami.', }; } const CarDetailPage = () => { const params = useParams(); const car = cars.find((car) => car.slug === params.slug); if (!car) { return <div>Mobil tidak ditemukan</div>; } return ( <div> <h1>{car.name}</h1> <p>Harga: Rp {car.price.toLocaleString()}</p> <p>{car.description}</p> </div> ); }; export default CarDetailPage; Di halaman detail mobil, kita menggunakan parameter slug untuk menemukan data mobil dari array cars. Fungsi generateMetadata mengembalikan metadata yang unik untuk setiap mobil, seperti title dan description, berdasarkan informasi dari dummy data. Jika mobil tidak ditemukan, metadata akan diatur untuk menunjukkan bahwa mobil tersebut tidak ada. Dengan cara ini, setiap halaman detail mobil memiliki metadata yang relevan untuk SEO, sehingga membantu mesin pencari memberikan informasi yang lebih akurat dan meningkatkan peluang website ditemukan oleh calon pembeli. Tips Meningkatkan SEO Organik pada Proyek Next.js SEO organik sangat penting untuk meningkatkan visibilitas website di mesin pencari seperti Google tanpa menggunakan iklan berbayar. Berikut adalah tiga tips praktis yang bisa kamu terapkan pada proyek Next.js untuk meningkatkan SEO organik, dilengkapi dengan contoh koding yang relevan. 1. Menggunakan generateMetadata untuk Meta Tags Dinamis Mengoptimalkan meta tags seperti title, description, dan keywords pada setiap halaman website adalah salah satu cara terbaik untuk meningkatkan SEO organik. Dengan Next.js, kamu bisa menggunakan fungsi generateMetadata untuk membuat meta tags yang dinamis berdasarkan konten halaman. Ini membantu mesin pencari memahami konten halaman dengan lebih baik. Contoh kode: // app/products/[slug]/page.tsx import { useParams } from 'next/navigation'; const products = [ { id: 1, name: 'Laptop Gaming', slug: 'laptop-gaming', price: 15000000, description: 'Laptop Gaming dengan performa tinggi untuk bermain game.' }, { id: 2, name: 'Smartphone 5G', slug: 'smartphone-5g', price: 8000000, description: 'Smartphone dengan teknologi 5G terbaru dan kamera canggih.' }, ]; export async function generateMetadata({ params }) { const product = products.find((p) => p.slug === params.slug); if (product) { return { title: `${product.name} - Produk Terbaik`, description: `${product.name} dengan harga Rp ${product.price.toLocaleString()}. ${product.description}`, }; } return { title: 'Produk Tidak Ditemukan', description: 'Produk yang Anda cari tidak tersedia.', }; } const ProductDetail = () => { const params = useParams(); const product = products.find((p) => p.slug === params.slug); if (!product) { return <div>Produk tidak ditemukan</div>; } return ( <div> <h1>{product.name}</h1> <p>Harga: Rp {product.price.toLocaleString()}</p> <p>{product.description}</p> </div> ); }; export default ProductDetail; Dengan generateMetadata, setiap halaman produk memiliki meta tags yang spesifik dan relevan, yang akan membantu meningkatkan SEO untuk halaman tersebut. 2. Mengoptimalkan Penggunaan Heading Tags Penggunaan heading tags seperti <h1>, <h2>, dan seterusnya sangat penting untuk membantu mesin pencari memahami struktur konten website. Pastikan setiap halaman memiliki hanya satu <h1> tag yang menggambarkan konten utama, dan gunakan heading lain untuk mendukung struktur konten. Contoh kode: // app/about/page.tsx const AboutPage = () => { return ( <div> <h1>Tentang Kami</h1> <p>Kami adalah perusahaan teknologi yang menyediakan produk-produk terbaik untuk kebutuhan Anda.</p> <h2>Misi Kami</h2> <p>Misi kami adalah memberikan produk berkualitas tinggi dengan layanan terbaik kepada pelanggan kami.</p> <h2>Visi Kami</h2> <p>Visi kami adalah menjadi pemimpin dalam inovasi teknologi dan solusi digital di pasar global.</p> </div> ); }; export default AboutPage; Dengan struktur heading yang jelas dan konsisten, konten website lebih mudah diindeks oleh mesin pencari, yang dapat meningkatkan SEO organik. 3. Menyediakan Sitemap untuk Mempermudah Indeksasi Sitemap adalah file XML yang memberikan informasi kepada mesin pencari tentang halaman-halaman penting di website. Dengan Next.js, kamu bisa membuat sitemap secara otomatis untuk membantu meningkatkan indeksasi konten oleh mesin pencari, yang pada akhirnya meningkatkan SEO organik. Contoh kode untuk membuat sitemap di Next.js: // pages/sitemap.xml.tsx import { GetServerSideProps } from 'next'; import { format } from 'date-fns'; const Sitemap = () => null; export const getServerSideProps: GetServerSideProps = async ({ res }) => { const baseUrl = '<https://yourwebsite.com>'; const today = format(new Date(), 'yyyy-MM-dd'); const staticPages = [ `${baseUrl}/`, `${baseUrl}/about`, `${baseUrl}/products`, ]; const sitemap = `<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="<http://www.sitemaps.org/schemas/sitemap/0.9>"> ${staticPages .map((url) => { return ` <url> <loc>${url}</loc> <lastmod>${today}</lastmod> </url> `; }) .join('')} </urlset>`; res.setHeader('Content-Type', 'text/xml'); res.write(sitemap); res.end(); return { props: {}, }; }; export default Sitemap; Dengan menyediakan sitemap, kamu memberi petunjuk kepada mesin pencari tentang halaman mana yang harus diindeks, yang dapat mempercepat proses indeksasi dan membantu SEO organik. Kesalahan Utama Ketika Memelihara SEO pada Proyek Next.js Memelihara SEO pada proyek Next.js membutuhkan perhatian khusus untuk memastikan bahwa mesin pencari dapat mengindeks dan menampilkan konten dengan baik. Namun, ada beberapa kesalahan umum yang sering dilakukan, yang dapat mengurangi efektivitas SEO. Berikut adalah tiga kesalahan utama yang harus dihindari, dilengkapi dengan contoh koding lengkap. 1. Tidak Menggunakan Meta Tags Dinamis Salah satu kesalahan terbesar adalah tidak memanfaatkan meta tags dinamis pada halaman yang berbeda. Meta tags seperti title, description, dan keywords sangat penting untuk SEO. Jika semua halaman menggunakan meta tags yang sama, maka mesin pencari tidak dapat memahami perbedaan konten antara satu halaman dengan yang lainnya. Contoh kesalahan: // app/products/page.tsx export default function ProductsPage() { return ( <div> <h1>Daftar Produk</h1> <p>Temukan berbagai produk di toko kami.</p> </div> ); } // Tidak ada meta tags dinamis untuk mengoptimalkan SEO di halaman ini. Contoh perbaikan: // app/products/page.tsx export async function generateMetadata() { return { title: 'Daftar Produk - Toko Online Terbaik', description: 'Jelajahi koleksi produk terbaru dan terbaik hanya di toko online kami.', }; } export default function ProductsPage() { return ( <div> <h1>Daftar Produk</h1> <p>Temukan berbagai produk di toko kami.</p> </div> ); } Dengan menggunakan generateMetadata, setiap halaman memiliki meta tags yang unik dan relevan, yang membantu mesin pencari mengindeks konten secara lebih baik. 2. Tidak Mengoptimalkan Struktur Heading Kesalahan lain yang sering dilakukan adalah menggunakan struktur heading (<h1>, <h2>, dll.) secara sembarangan. Setiap halaman harus memiliki satu <h1> tag yang menggambarkan konten utama, dan heading lainnya digunakan untuk mendukung struktur konten. Penggunaan heading yang berlebihan atau tidak konsisten dapat membingungkan mesin pencari. Contoh kesalahan: // app/about/page.tsx export default function AboutPage() { return ( <div> <h2>Tentang Kami</h2> <p>Kami menyediakan berbagai produk berkualitas tinggi.</p> <h2>Misi Kami</h2> <p>Memberikan layanan terbaik kepada pelanggan.</p> </div> ); } // Tidak ada penggunaan <h1>, dan <h2> digunakan lebih dari satu kali di satu level konten. Contoh perbaikan: // app/about/page.tsx export default function AboutPage() { return ( <div> <h1>Tentang Kami</h1> <p>Kami menyediakan berbagai produk berkualitas tinggi.</p> <h2>Misi Kami</h2> <p>Memberikan layanan terbaik kepada pelanggan.</p> </div> ); } Dengan menempatkan <h1> pada judul utama dan menggunakan <h2> secara tepat untuk subjudul, struktur halaman lebih mudah dipahami oleh mesin pencari. 3. Tidak Menyediakan Tautan Internal yang Relevan Kesalahan lain yang sering terjadi adalah mengabaikan penggunaan tautan internal. Tautan internal membantu mesin pencari untuk menjelajahi dan mengindeks seluruh halaman website dengan lebih baik. Menggunakan tautan internal yang relevan juga dapat meningkatkan pengalaman pengguna dengan memudahkan navigasi antarhalaman. Contoh kesalahan: // app/home/page.tsx export default function HomePage() { return ( <div> <h1>Selamat Datang di Toko Kami</h1> <p>Kami menyediakan berbagai macam produk berkualitas tinggi.</p> </div> ); } // Tidak ada tautan internal yang membantu pengguna menjelajahi halaman lain. Contoh perbaikan: // app/home/page.tsx import Link from 'next/link'; export default function HomePage() { return ( <div> <h1>Selamat Datang di Toko Kami</h1> <p>Kami menyediakan berbagai macam produk berkualitas tinggi.</p> <Link href="/products">Lihat Daftar Produk</Link> </div> ); } Dengan menambahkan tautan internal, mesin pencari lebih mudah menavigasi situs dan mengindeks halaman-halaman lain yang relevan. Tautan ini juga meningkatkan interaksi pengguna di website. Penutup Dengan memahami dan menerapkan cara-cara untuk meningkatkan SEO pada proyek Next.js, kamu sudah berada di jalur yang tepat untuk membangun website yang lebih mudah ditemukan di mesin pencari dan mendatangkan lebih banyak pengunjung secara organik. Namun, perjalanan belajar tidak berhenti di sini. Kamu bisa terus mengembangkan kemampuanmu dengan bergabung di BuildWithAngga. Di BuildWithAngga, kamu bisa belajar bersama mentor expert yang akan membantu kamu memahami lebih dalam tentang web development dan SEO. Selain itu, kamu akan mendapatkan banyak benefit, seperti akses selamanya ke materi pembelajaran, portfolio berkualitas yang siap memukau calon klien atau perusahaan, konsultasi langsung dengan mentor untuk mengatasi masalah teknis, serta benefit menarik lainnya yang akan mempercepat proses belajar kamu. Mari tingkatkan kemampuan coding dan wujudkan impianmu bersama BuildWithAngga!

Kelas Tutorial Next JS 14 Pemula: App Router vs Pages Router di BuildWithAngga

Tutorial Next JS 14 Pemula: App Router vs Pages Router

Routing merupakan salah satu komponen penting dalam setiap projek website. Dengan routing yang baik, pengguna dapat mengakses halaman-halaman di dalam website dengan lebih mudah, memberikan pengalaman yang nyaman dan responsif. Routing yang tertata dengan baik juga membantu developer dalam mengelola navigasi antar halaman, sehingga setiap bagian dari website bisa diakses secara efisien. Pentingnya routing membuat developer harus memilih dan menerapkan metode routing yang sesuai dengan kebutuhan projek web development mereka. Next.js hadir sebagai salah satu framework JavaScript modern yang sangat populer dan mendukung konsep file-based routing. Ini berarti setiap file yang diletakkan di dalam folder tertentu secara otomatis menjadi rute yang bisa diakses pada URL. Dalam Next.js 14, ada dua konsep utama terkait routing yang perlu dipahami, yaitu App Router dan Pages Router. Kedua konsep ini memiliki tujuan yang sama, yaitu mengelola navigasi halaman, namun dengan cara kerja yang berbeda. Pada artikel ini, kita akan membahas secara singkat mengenai perbedaan kedua jenis router tersebut untuk membantu pemula memahami bagaimana mereka bekerja di dalam Next.js 14. Apa Itu App Router di Next.js? App Router di Next.js adalah pendekatan modern untuk pengelolaan routing yang diperkenalkan mulai dari Next.js 13 dan semakin dikembangkan di versi Next.js 14. Tidak seperti Pages Router yang menggunakan folder pages, App Router bekerja dengan folder app, di mana setiap file di dalamnya secara otomatis menjadi rute di aplikasi. Konsep ini menawarkan pendekatan yang lebih fleksibel dan modular dalam pengelolaan rute, serta mendukung fitur-fitur canggih seperti React Server Components dan nested routing. Berikut contoh bagaimana cara membuat beberapa rute dengan App Router: // app/page.tsx import React from 'react'; const HomePage = () => { return ( <div> <h1>Selamat Datang di Home Page</h1> <p>Ini adalah halaman utama menggunakan App Router di Next.js 14.</p> </div> ); } export default HomePage; Pada contoh di atas, file page.tsx yang berada di folder app secara otomatis menjadi halaman utama yang diakses melalui rute /. Ini menunjukkan betapa mudahnya membuat rute di App Router tanpa perlu konfigurasi yang rumit. Jika Anda ingin membuat halaman lain seperti halaman "Tentang", cukup tambahkan file baru: // app/about/page.tsx import React from 'react'; const AboutPage = () => { return ( <div> <h1>Halaman Tentang</h1> <p>Ini adalah halaman tentang menggunakan App Router di Next.js 14.</p> </div> ); } export default AboutPage; Dengan struktur ini, halaman About akan dapat diakses melalui /about tanpa tambahan konfigurasi apa pun. Anda juga bisa membuat subrute dengan struktur file yang lebih dalam. Misalnya, untuk halaman produk dengan subrute: // app/products/[id]/page.tsx import React from 'react'; const ProductDetail = ({ params }: { params: { id: string } }) => { return ( <div> <h1>Detail Produk {params.id}</h1> <p>Informasi produk dengan ID {params.id}.</p> </div> ); } export default ProductDetail; File di atas akan menghasilkan rute dinamis untuk halaman detail produk yang dapat diakses melalui /products/[id], di mana [id] adalah parameter dinamis. Misalnya, jika Anda ingin melihat produk dengan ID 123, Anda dapat mengakses /products/123. Beberapa keuntungan lain menggunakan App Router di Next.js 14 adalah: Modular dan Terorganisir: Struktur rute lebih rapi dengan memisahkan file berdasarkan fungsinya. Contohnya, logika untuk data fetching dapat dipisah ke dalam komponen server, sedangkan UI klien tetap di komponen klien.Optimisasi Performa: Dengan React Server Components, bagian tertentu dari halaman bisa dirender di server dan dikirim ke klien, mengurangi waktu loading di browser.Nested Routes: Mendukung pembuatan rute bertingkat (nested routes), yang sangat membantu ketika membuat struktur halaman yang kompleks seperti aplikasi e-commerce dengan halaman produk, ulasan, dan kategori. Dengan semua fitur yang ditawarkan, App Router cocok digunakan dalam proyek yang membutuhkan pengelolaan rute yang lebih kompleks dan performa tinggi. Perbandingan App Router vs Pages Router di Next.js 14 KriteriaApp RouterPages RouterFlexibilitySangat fleksibel, mendukung React Server Components dan nested routing. Misalnya, jika Anda memiliki halaman produk dengan subhalaman untuk ulasan dan detail produk, App Router memungkinkan Anda membuat struktur seperti /product/[id]/reviews dan /product/[id]/details dengan mudah.Fleksibilitas lebih terbatas, namun tetap mendukung kebutuhan routing sederhana seperti /about atau /contact. Misalnya, aplikasi portofolio atau landing page dapat dikelola dengan mudah menggunakan Pages Router.Folder StructureMenggunakan folder app, setiap file atau folder di dalamnya otomatis menjadi rute. Sebagai contoh, app/blog/page.tsx akan menjadi /blog di URL. Folder terstruktur dengan baik, memungkinkan pemisahan logika server dan klien secara terorganisir.Menggunakan folder pages, di mana setiap file di dalamnya langsung menjadi rute. Misalnya, file pages/about.js akan otomatis menjadi /about. Struktur ini lebih sederhana, memudahkan developer untuk melihat secara langsung rute yang tersedia dalam aplikasi.Use Case ScenarioCocok untuk aplikasi dengan rute kompleks, seperti aplikasi e-commerce atau sistem manajemen yang memiliki banyak halaman dinamis, termasuk integrasi SSR dan SSG untuk optimasi performa.Cocok untuk aplikasi kecil hingga menengah, seperti blog sederhana, portofolio, atau aplikasi satu halaman (SPA) yang tidak memerlukan struktur rute yang kompleks atau fitur SSR yang rumit. Dengan App Router, Anda mendapatkan kontrol yang lebih baik dalam hal pembagian komponen server dan klien, sedangkan Pages Router lebih cocok untuk aplikasi yang membutuhkan setup cepat dengan rute yang sederhana. Contoh Struktur Folder Lengkap: App Router vs Pages Router Berikut adalah contoh struktur folder lengkap untuk App Router dan Pages Router di Next.js agar lebih jelas bagaimana kedua pendekatan ini diimplementasikan dalam proyek. Struktur Folder: App Router Pada App Router, semua file rute diletakkan di dalam folder app. Setiap file atau folder di dalamnya secara otomatis menjadi rute sesuai dengan struktur folder tersebut. my-next-app/ ├── app/ │ ├── layout.tsx // Layout utama untuk semua halaman │ ├── page.tsx // Halaman utama (rute "/") │ ├── about/ │ │ └── page.tsx // Halaman tentang (rute "/about") │ ├── products/ │ │ ├── page.tsx // Halaman produk (rute "/products") │ │ └── [id]/ │ │ └── page.tsx // Halaman detail produk dengan ID dinamis (rute "/products/[id]") │ ├── blog/ │ │ ├── layout.tsx // Layout khusus untuk semua halaman blog │ │ ├── page.tsx // Halaman utama blog (rute "/blog") │ │ └── [slug]/ │ │ └── page.tsx // Halaman artikel blog dinamis (rute "/blog/[slug]") ├── public/ │ └── favicon.ico // Ikon situs ├── styles/ │ └── globals.css // CSS global └── next.config.js // Konfigurasi Next.js Pada struktur di atas: File layout.tsx digunakan untuk mendefinisikan layout yang bisa digunakan di seluruh halaman dalam app.Folder dinamis menggunakan tanda kurung seperti [id] dan [slug] untuk mendukung rute dinamis.Setiap halaman, seperti about/page.tsx, secara otomatis diakses melalui URL yang sesuai dengan struktur foldernya. Struktur Folder: Pages Router Untuk Pages Router, semua file rute diletakkan di dalam folder pages. Setiap file di dalam folder ini menjadi rute otomatis berdasarkan nama file atau folder tersebut. my-next-app/ ├── pages/ │ ├── index.js // Halaman utama (rute "/") │ ├── about.js // Halaman tentang (rute "/about") │ ├── products/ │ │ └── index.js // Halaman produk (rute "/products") │ ├── products/ │ │ └── [id].js // Halaman detail produk dengan ID dinamis (rute "/products/[id]") │ ├── blog/ │ │ ├── index.js // Halaman utama blog (rute "/blog") │ │ └── [slug].js // Halaman artikel blog dinamis (rute "/blog/[slug]") ├── public/ │ └── favicon.ico // Ikon situs ├── styles/ │ └── globals.css // CSS global └── next.config.js // Konfigurasi Next.js Pada struktur di atas: File index.js di dalam pages menjadi halaman utama yang dapat diakses melalui /.Rute dinamis ditangani dengan file [id].js atau [slug].js, mirip dengan App Router.Tidak ada layout terpisah seperti di App Router, sehingga struktur ini lebih sederhana dan langsung. Fitur Segments di App Router Next.js Segments dalam App Router di Next.js adalah bagian dari URL yang dipisahkan oleh garis miring /. Setiap segmen ini dapat berupa rute statis atau dinamis. Dalam App Router, Anda dapat memanfaatkan segmen untuk membagi dan mengatur rute menjadi lebih modular dan fleksibel, termasuk dukungan untuk rute dinamis, parameter opsional, dan pengelompokan. Berikut beberapa konsep segmen yang bisa diterapkan di App Router: Static Segment: Rute statis seperti /products atau /about.Dynamic Segment: Rute dengan parameter dinamis seperti /products/[id].Optional Segment: Segmen opsional yang mungkin ada atau tidak dalam URL.Parallel Routes: Menangani beberapa segmen yang dapat muncul secara paralel. Contoh Penerapan Segments di App Router Kita akan melihat contoh bagaimana segmen bekerja di App Router dengan mengimplementasikan rute untuk produk dengan ID dinamis dan kategori opsional. Struktur Folder: app/ ├── products/ │ ├── [id]/ │ │ ├── page.tsx // Halaman detail produk │ │ └── [category]/ │ └── page.tsx // Halaman produk dengan kategori opsional Rute Dinamis (Dynamic Segment) untuk Produk Berdasarkan ID: // app/products/[id]/page.tsx import React from 'react'; const ProductDetail = ({ params }: { params: { id: string } }) => { return ( <div> <h1>Detail Produk {params.id}</h1> <p>Informasi lengkap tentang produk dengan ID {params.id}.</p> </div> ); } export default ProductDetail; Pada contoh ini, segmen [id] digunakan untuk menangani rute dinamis. Ketika pengguna mengakses /products/123, halaman ini akan menampilkan informasi produk dengan ID 123. Segmen dinamis [id] memungkinkan rute ini menangani berbagai nilai ID tanpa membuat rute statis untuk setiap produk. Segmen Opsional (Optional Segment) untuk Kategori: // app/products/[id]/[category]/page.tsx import React from 'react'; const ProductCategory = ({ params }: { params: { id: string; category?: string } }) => { return ( <div> <h1>Produk {params.id}</h1> {params.category ? ( <p>Kategori: {params.category}</p> ) : ( <p>Produk ini tidak memiliki kategori khusus.</p> )} </div> ); } export default ProductCategory; Di sini, kita menambahkan segmen [category] di dalam rute [id] untuk menangani kategori produk yang mungkin opsional. Ketika pengguna mengakses /products/123/electronics, kategori electronics akan ditampilkan. Namun, jika hanya mengakses /products/123, maka produk akan tetap ditampilkan tanpa kategori, dan pesan default akan diberikan. Kesimpulan Static Segment digunakan untuk rute yang selalu sama, seperti /products atau /about.Dynamic Segment memungkinkan Anda menangani berbagai nilai, seperti ID produk atau nama kategori, tanpa membuat rute statis untuk setiap variasi.Optional Segment digunakan untuk menangani bagian URL yang mungkin ada atau tidak, sehingga Anda bisa membuat rute yang lebih fleksibel. Dengan fitur segments di App Router, Anda dapat membangun rute yang lebih dinamis dan modular, mengurangi kompleksitas dalam menangani URL yang bervariasi dalam aplikasi Anda. Apa Itu Dynamic Routes? Dynamic routes adalah rute yang memungkinkan URL untuk menangani parameter dinamis. Contohnya, dalam sebuah aplikasi e-commerce, halaman detail produk mungkin perlu menangani URL seperti /products/123, di mana 123 adalah ID dari produk tersebut. Dengan dynamic routes, Anda dapat membuat satu rute yang menangani berbagai nilai dinamis, seperti ID atau slug produk, tanpa perlu membuat rute terpisah untuk setiap produk. Dynamic routes sangat berguna ketika Anda memiliki data yang bervariasi, seperti postingan blog, produk, atau pengguna, yang diakses melalui URL dinamis. Dynamic Routes di App Router Dalam App Router di Next.js, dynamic routes diimplementasikan dengan membuat folder yang menggunakan tanda kurung ([ ]) di sekitar nama parameter dinamis. Misalnya, jika Anda ingin membuat rute dinamis untuk detail produk berdasarkan ID, Anda bisa membuat folder [id]. Berikut adalah contoh implementasi dynamic routes di App Router: // app/products/[id]/page.tsx import React from 'react'; const ProductDetail = ({ params }: { params: { id: string } }) => { return ( <div> <h1>Detail Produk {params.id}</h1> <p>Ini adalah informasi produk dengan ID {params.id}.</p> </div> ); } export default ProductDetail; Pada contoh di atas: Folder products berisi folder dinamis [id].File page.tsx di dalam folder [id] akan menangani URL seperti /products/123, di mana 123 adalah nilai dinamis untuk ID produk.Parameter dinamis id diakses melalui properti params, yang secara otomatis diteruskan ke komponen oleh Next.js. Anda dapat menambahkan rute dinamis tambahan dengan struktur folder yang lebih dalam, seperti /products/[id]/reviews, menggunakan folder dinamis lainnya seperti [id] di dalam products. Dynamic Routes di Pages Router Dalam Pages Router, dynamic routes juga diimplementasikan dengan membuat file menggunakan tanda kurung ([ ]). Namun, daripada menggunakan folder, Anda akan membuat file dengan nama parameter dinamis di dalam folder pages. Berikut adalah contoh implementasi dynamic routes di Pages Router: // pages/products/[id].js import React from 'react'; import { useRouter } from 'next/router'; const ProductDetail = () => { const router = useRouter(); const { id } = router.query; return ( <div> <h1>Detail Produk {id}</h1> <p>Ini adalah informasi produk dengan ID {id}.</p> </div> ); } export default ProductDetail; Pada contoh di atas: File [id].js di dalam folder products menangani rute dinamis untuk produk berdasarkan ID, seperti /products/123.Untuk mendapatkan nilai dinamis dari URL, digunakan hook useRouter dari Next.js. router.query.id memberikan akses ke parameter id dari URL. Dynamic routes di Pages Router bekerja mirip dengan App Router, tetapi perbedaannya terletak pada struktur folder dan cara pengambilan parameter dari URL (menggunakan useRouter() di Pages Router). Apa Itu Nested Routing? Nested routing adalah konsep di mana satu rute dapat memiliki rute anak atau subrute yang terkait. Ini berarti bahwa di dalam satu halaman atau komponen, Anda bisa memiliki beberapa bagian atau halaman lain yang diakses sebagai subrute. Nested routing sangat bermanfaat untuk aplikasi yang memiliki struktur hierarkis atau rute yang lebih kompleks, seperti aplikasi e-commerce dengan halaman produk yang memiliki tab untuk ulasan, detail, dan spesifikasi produk. Nested Routing di App Router Dalam App Router di Next.js, nested routing diimplementasikan dengan menggunakan folder bertingkat di dalam folder app. Struktur folder ini mencerminkan bagaimana rute dan subrute akan muncul di URL. Setiap folder mewakili bagian dari rute, sehingga Anda bisa dengan mudah membuat rute bertingkat. Berikut contoh implementasi nested routing di App Router: // app/products/[id]/layout.tsx import React from 'react'; const ProductLayout = ({ children }: { children: React.ReactNode }) => { return ( <div> <h1>Halaman Produk</h1> <div>{children}</div> {/* Subrute akan di-render di sini */} </div> ); } export default ProductLayout; // app/products/[id]/page.tsx import React from 'react'; const ProductDetail = ({ params }: { params: { id: string } }) => { return ( <div> <h2>Detail Produk {params.id}</h2> <p>Informasi detail tentang produk dengan ID {params.id}.</p> </div> ); } export default ProductDetail; // app/products/[id]/reviews/page.tsx import React from 'react'; const ProductReviews = ({ params }: { params: { id: string } }) => { return ( <div> <h2>Ulasan Produk {params.id}</h2> <p>Berikut adalah ulasan untuk produk dengan ID {params.id}.</p> </div> ); } export default ProductReviews; Pada struktur ini: Folder products/[id] memiliki file layout.tsx yang bertindak sebagai layout untuk semua halaman terkait produk. Komponen children di layout ini akan menampilkan halaman yang lebih spesifik seperti detail atau ulasan produk.File page.tsx di dalam folder [id] menangani rute utama produk, misalnya /products/123.Folder reviews di dalam [id] membuat rute tambahan, sehingga rute /products/123/reviews menampilkan halaman ulasan produk. Komponen ini di-render di dalam children pada ProductLayout. Dengan nested routing, Anda bisa mengatur struktur halaman yang lebih kompleks, seperti /products/123, /products/123/reviews, atau /products/123/specifications. Nested Routing di Pages Router Dalam Pages Router, nested routing juga bisa diterapkan dengan struktur folder bertingkat. Meskipun Pages Router tidak memiliki konsep layout bawaan seperti App Router, Anda bisa menggunakan komponen React biasa untuk menangani layout dan navigasi antar subhalaman. Berikut adalah contoh implementasi nested routing di Pages Router: // pages/products/[id].js import React from 'react'; import Link from 'next/link'; const ProductDetail = ({ id }) => { return ( <div> <h2>Detail Produk {id}</h2> <p>Informasi tentang produk dengan ID {id}.</p> <nav> <Link href={`/products/${id}/reviews`}>Lihat Ulasan</Link> </nav> </div> ); } export async function getServerSideProps(context) { const { id } = context.params; return { props: { id }, }; } export default ProductDetail; // pages/products/[id]/reviews.js import React from 'react'; const ProductReviews = ({ id }) => { return ( <div> <h2>Ulasan Produk {id}</h2> <p>Berikut adalah ulasan untuk produk dengan ID {id}.</p> </div> ); } export async function getServerSideProps(context) { const { id } = context.params; return { props: { id }, }; } export default ProductReviews; Pada struktur ini: File [id].js di dalam folder products menangani halaman detail produk pada rute /products/[id].Folder products/[id] berisi file reviews.js, yang menjadi subrute untuk menampilkan ulasan produk dengan rute /products/[id]/reviews.Navigasi antar subrute dilakukan melalui komponen Link di halaman utama produk. Perbedaan utamanya adalah dalam Pages Router, layout atau tampilan halaman biasanya dibuat di dalam setiap file, sedangkan di App Router, layout bisa dipisah dengan lebih modular menggunakan file layout.tsx. Kesimpulan App Router mendukung nested routing secara lebih modular dengan layout.tsx yang memungkinkan subrute di-render dalam komponen layout yang sama, sehingga lebih cocok untuk aplikasi dengan struktur rute yang kompleks.Pages Router menggunakan struktur folder yang serupa untuk nested routing, tetapi tidak memiliki fitur layout bawaan, sehingga perlu menggunakan komponen React biasa untuk mengelola tampilan antar halaman. Latihan Menerapkan App Router pada Proyek Simple E-commerce: CRUD Products dan Transaction Pada latihan ini, kita akan mencoba menerapkan App Router di Next.js untuk membangun proyek e-commerce sederhana dengan fitur CRUD untuk produk dan transaksi. Dengan menggunakan App Router, kita dapat memanfaatkan routing yang fleksibel dan modular, yang sangat cocok untuk aplikasi seperti e-commerce. Proyek ini akan terdiri dari dua bagian utama: manajemen produk (CRUD) dan transaksi. Membuat CRUD Products Untuk memulai, kita akan membuat rute untuk menampilkan daftar produk, menambahkan produk baru, mengedit produk, dan menghapus produk. Setiap rute ini akan dikelola oleh App Router di dalam folder app. Struktur Folder: app/ ├── products/ │ ├── page.tsx // Menampilkan daftar produk │ ├── create/ │ │ └── page.tsx // Menambahkan produk baru │ └── [id]/ │ ├── page.tsx // Menampilkan detail produk │ └── edit/ │ └── page.tsx // Mengedit produk Menampilkan Daftar Produk: // app/products/page.tsx import React from 'react'; const ProductsPage = () => { const products = [ { id: 1, name: 'Produk A', price: 10000 }, { id: 2, name: 'Produk B', price: 20000 }, ]; return ( <div> <h1>Daftar Produk</h1> <ul> {products.map((product) => ( <li key={product.id}> {product.name} - Rp {product.price} <a href={`/products/${product.id}`}>Detail</a> <a href={`/products/${product.id}/edit`}>Edit</a> </li> ))} </ul> <a href="/products/create">Tambah Produk Baru</a> </div> ); }; export default ProductsPage; Di halaman ini, kita menampilkan daftar produk beserta tautan untuk melihat detail produk atau mengedit produk. Menambahkan Produk Baru: // app/products/create/page.tsx import React, { useState } from 'react'; const CreateProductPage = () => { const [name, setName] = useState(''); const [price, setPrice] = useState(''); const handleSubmit = (e) => { e.preventDefault(); console.log({ name, price }); // Di sini bisa ditambahkan logika untuk menyimpan data }; return ( <div> <h1>Tambah Produk Baru</h1> <form onSubmit={handleSubmit}> <input type="text" placeholder="Nama Produk" value={name} onChange={(e) => setName(e.target.value)} /> <input type="number" placeholder="Harga Produk" value={price} onChange={(e) => setPrice(e.target.value)} /> <button type="submit">Simpan</button> </form> </div> ); }; export default CreateProductPage; Form ini memungkinkan pengguna untuk menambahkan produk baru ke dalam daftar. Anda bisa memperluas logika dengan menambahkan API untuk menyimpan data ke database. Mengedit Produk: // app/products/[id]/edit/page.tsx import React, { useState } from 'react'; const EditProductPage = ({ params }: { params: { id: string } }) => { const [name, setName] = useState('Produk A'); // Nilai awal bisa diambil dari API const [price, setPrice] = useState(10000); // Nilai awal bisa diambil dari API const handleSubmit = (e) => { e.preventDefault(); console.log({ id: params.id, name, price }); // Di sini bisa ditambahkan logika untuk mengupdate data }; return ( <div> <h1>Edit Produk {params.id}</h1> <form onSubmit={handleSubmit}> <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> <input type="number" value={price} onChange={(e) => setPrice(e.target.value)} /> <button type="submit">Simpan Perubahan</button> </form> </div> ); }; export default EditProductPage; Halaman ini memungkinkan pengguna untuk mengedit produk berdasarkan ID produk. Anda bisa menggunakan API untuk mengambil dan mengupdate data produk. Membuat CRUD Transactions Selanjutnya, kita akan menambahkan rute untuk transaksi yang mengikuti pola serupa seperti manajemen produk. Struktur Folder: app/ ├── transactions/ │ ├── page.tsx // Menampilkan daftar transaksi │ ├── create/ │ │ └── page.tsx // Menambahkan transaksi baru │ └── [id]/ │ ├── page.tsx // Menampilkan detail transaksi │ └── edit/ │ └── page.tsx // Mengedit transaksi Menampilkan Daftar Transaksi: // app/transactions/page.tsx import React from 'react'; const TransactionsPage = () => { const transactions = [ { id: 1, product: 'Produk A', total: 2, amount: 20000 }, { id: 2, product: 'Produk B', total: 1, amount: 20000 }, ]; return ( <div> <h1>Daftar Transaksi</h1> <ul> {transactions.map((transaction) => ( <li key={transaction.id}> {transaction.product} - {transaction.total} item - Rp {transaction.amount} <a href={`/transactions/${transaction.id}`}>Detail</a> <a href={`/transactions/${transaction.id}/edit`}>Edit</a> </li> ))} </ul> <a href="/transactions/create">Tambah Transaksi Baru</a> </div> ); }; export default TransactionsPage; Halaman ini menampilkan daftar transaksi, dan menyediakan tautan untuk melihat detail transaksi atau mengeditnya. Menambahkan Transaksi Baru: // app/transactions/create/page.tsx import React, { useState } from 'react'; const CreateTransactionPage = () => { const [product, setProduct] = useState(''); const [total, setTotal] = useState(''); const [amount, setAmount] = useState(''); const handleSubmit = (e) => { e.preventDefault(); console.log({ product, total, amount }); // Di sini bisa ditambahkan logika untuk menyimpan data transaksi }; return ( <div> <h1>Tambah Transaksi Baru</h1> <form onSubmit={handleSubmit}> <input type="text" placeholder="Produk" value={product} onChange={(e) => setProduct(e.target.value)} /> <input type="number" placeholder="Jumlah" value={total} onChange={(e) => setTotal(e.target.value)} /> <input type="number" placeholder="Total Harga" value={amount} onChange={(e) => setAmount(e.target.value)} /> <button type="submit">Simpan</button> </form> </div> ); }; export default CreateTransactionPage; Form ini memungkinkan pengguna untuk menambahkan transaksi baru dengan memasukkan produk, jumlah, dan harga total. Dengan menggunakan App Router, Anda dapat mengelola rute secara modular, memisahkan setiap fitur (produk dan transaksi) menjadi halaman dan subrute yang terstruktur dengan baik. Contoh Kesalahan Saat Mengerjakan Routing pada Proyek Next.js Berikut adalah tiga contoh kesalahan umum yang sering terjadi ketika mengerjakan routing pada proyek Next.js, beserta contoh koding lengkapnya. Kesalahan 1: Tidak Mengatur Rute Dinamis dengan Benar Salah satu kesalahan umum adalah tidak menggunakan tanda kurung untuk parameter dinamis dalam rute. Misalnya, saat Anda ingin membuat rute dinamis untuk produk berdasarkan ID, tetapi Anda menggunakan nama file biasa, bukannya tanda kurung ([id]). Kesalahan: // app/products/id/page.tsx (Tidak menggunakan tanda kurung [id]) import React from 'react'; const ProductDetail = () => { return ( <div> <h1>Detail Produk</h1> <p>Ini adalah halaman produk tanpa parameter dinamis.</p> </div> ); } export default ProductDetail; Pada contoh ini, file id/page.tsx tidak akan menangani parameter dinamis seperti /products/123 karena Next.js menganggap id sebagai rute statis. Untuk mengatasi masalah ini, Anda harus menggunakan tanda kurung untuk membuat rute dinamis yang benar. Perbaikan: // app/products/[id]/page.tsx (Menggunakan tanda kurung [id] untuk parameter dinamis) import React from 'react'; const ProductDetail = ({ params }: { params: { id: string } }) => { return ( <div> <h1>Detail Produk {params.id}</h1> <p>Informasi produk dengan ID {params.id}.</p> </div> ); } export default ProductDetail; Kesalahan 2: Tidak Menggunakan Link dengan Benar Kesalahan lain yang sering terjadi adalah menggunakan tag <a> langsung tanpa menggunakan komponen <Link> dari Next.js. Ini bisa menyebabkan halaman direload sepenuhnya ketika berpindah halaman, padahal Next.js mendukung navigasi antar halaman secara client-side. Kesalahan: // pages/products/index.js import React from 'react'; const ProductsPage = () => { return ( <div> <h1>Daftar Produk</h1> <a href="/products/123">Lihat Detail Produk</a> {/* Ini akan menyebabkan full reload */} </div> ); } export default ProductsPage; Pada contoh ini, penggunaan <a href="/products/123"> akan menyebabkan halaman direload penuh, yang mengabaikan optimasi client-side routing dari Next.js. Perbaikan: // pages/products/index.js import React from 'react'; import Link from 'next/link'; const ProductsPage = () => { return ( <div> <h1>Daftar Produk</h1> <Link href="/products/123"> <a>Lihat Detail Produk</a> {/* Menggunakan Link untuk client-side navigation */} </Link> </div> ); } export default ProductsPage; Dengan menggunakan <Link>, Next.js akan melakukan navigasi antar halaman tanpa reload penuh, yang jauh lebih cepat dan lebih efisien. Kesalahan 3: Tidak Menyertakan Default Page di Nested Routes Ketika menggunakan nested routes, kesalahan umum lainnya adalah tidak menyertakan file page.tsx atau index.js pada rute utama, sehingga menyebabkan error saat mengakses rute induk. Kesalahan: // app/products/[id]/reviews/page.tsx (Hanya ada subrute, tapi tidak ada rute induk) import React from 'react'; const ReviewsPage = ({ params }: { params: { id: string } }) => { return ( <div> <h1>Ulasan untuk Produk {params.id}</h1> </div> ); } export default ReviewsPage; Pada contoh ini, rute /products/123/reviews akan berfungsi dengan baik, tetapi jika Anda mencoba mengakses /products/123, Anda akan mendapatkan error karena tidak ada file page.tsx di folder [id]. Perbaikan: // app/products/[id]/page.tsx (Menambahkan halaman default untuk rute induk) import React from 'react'; const ProductDetail = ({ params }: { params: { id: string } }) => { return ( <div> <h1>Detail Produk {params.id}</h1> <p>Informasi produk dengan ID {params.id}.</p> </div> ); } export default ProductDetail; Dengan menambahkan halaman default di rute induk (/products/[id]/page.tsx), Anda dapat memastikan bahwa rute /products/123 dan subrute /products/123/reviews keduanya berfungsi dengan baik. Penutup Membangun proyek dengan Next.js, terutama dalam hal routing, membutuhkan pemahaman yang baik agar aplikasi berjalan dengan efisien dan mudah dikelola. Dengan menghindari kesalahan umum dan memahami konsep seperti dynamic routes serta nested routing, Anda dapat mengembangkan aplikasi yang lebih terstruktur dan performa tinggi. Bagi Anda yang ingin memperdalam ilmu web development, termasuk dalam pengembangan aplikasi dengan Next.js, Laravel, atau framework lainnya, Anda bisa belajar bersama mentor expert di Buildwithangga. Dengan bergabung, Anda akan mendapatkan berbagai benefit menarik seperti akses selamanya ke materi pembelajaran, portofolio berkualitas yang bisa ditampilkan kepada klien atau perekrut, konsultasi langsung dengan mentor untuk mendapatkan bimbingan dan saran, serta banyak lagi manfaat lainnya yang akan membantu Anda menjadi developer yang lebih handal. Ayo, tingkatkan skill Anda dan bangun karier yang lebih baik bersama Buildwithangga!