Skip to content

State vs Context & Penutup Chapter

Kapan Gunakan State?

Context = Local (Per Instance)

Setiap instance block punya context terpisah dan independen. Quiz #1 tidak tahu apa-apa tentang Quiz #2.

State = Global (Seluruh Halaman)

State dibagi antar semua block instances dan bahkan antar block types yang berbeda, selama mereka menggunakan namespace yang sama.

Contoh Kasus Nyata

3 instance quiz di satu halaman + 1 block "Solved Counter":

  • Context: pertanyaan, jawaban, solved status → per quiz instance
  • State: total quiz yang dijawab benar → global counter yang diupdate dari semua instance

Membuat Block Baru: Solved Counter

Scaffold Plugin Baru

bash
cd /path/to/wp-content/plugins
npx @wordpress/create-block@latest solved-counter --template @wordpress/create-block/interactive-template

Aktivasi plugin di WP Admin → Plugins.

render.php untuk Solved Counter

php
<?php
// src/render.php (solved-counter plugin)

// Inisialisasi state — namespace HARUS SAMA dengan quiz block
wp_interactivity_state("create-block", array(
  "solvedCount" => 0
));
?>
<div data-wp-interactive="create-block">
  <p>Questions solved: 
    <strong>
      <span data-wp-text="state.solvedCount"></span>
    </strong>
  </p>
</div>

Kunci: data-wp-interactive="create-block" dan wp_interactivity_state("create-block", ...) — namespace harus cocok dengan quiz block.

wp_interactivity_state() — Set Global State dari PHP

Di Quiz Block (render.php)

php
<?php
// src/render.php (interactivity-quiz plugin)

wp_interactivity_state("create-block", array(
  "solvedCount" => 0,
  "skyColor" => "blue"   // contoh state tambahan
));

// ... rest of render.php
?>

Namespace sebagai "Glue"

block.json → name: "create-block/interactivity-quiz"
                     ^^^^^^^^^^^^
                     Ini adalah NAMESPACE

store("create-block", { ... })  ← JS store
wp_interactivity_state("create-block", ...)  ← PHP state  
data-wp-interactive="create-block"  ← HTML directive

Semua harus pakai namespace yang sama agar terhubung.

Mengakses State dari JavaScript

Destructure State dari Store

js
// src/view.js (interactivity-quiz plugin)
import { store, getContext } from "@wordpress/interactivity";

const { state } = store("create-block", {
  actions: {
    guessAttempt: () => {
      const context = getContext();
      
      if (!context.solved) {
        if (context.index === context.correctAnswer) {
          context.showCongrats = true;
          setTimeout(() => { context.solved = true; }, 1000);
          
          // INCREMENT GLOBAL STATE
          state.solvedCount++;
        } else {
          context.showSorry = true;
          setTimeout(() => { context.showSorry = false; }, 2600);
        }
      }
    },
  },
  callbacks: { /* ... */ },
});

Baris kunci: const { state } = store("create-block", { ... }) — destructure state dari return value store().

State Merging

Beberapa Block Bisa Set State

php
// Di quiz plugin:
wp_interactivity_state("create-block", array(
  "solvedCount" => 0,
  "skyColor" => "blue"
));

// Di solved-counter plugin:
wp_interactivity_state("create-block", array(
  "solvedCount" => 0,
  "grassColor" => "green"
));

WordPress Merge Otomatis

js
console.log(state);
// {
//   solvedCount: 0,      ← dari kedua plugin
//   skyColor: "blue",    ← dari quiz plugin
//   grassColor: "green"  ← dari counter plugin
// }

State dari berbagai block digabungkan secara cerdas oleh WordPress. Tidak ada konflik selama namespace sama.

Edge Case: Counter Tanpa Quiz

Karena solved-counter juga inisialisasi solvedCount: 0, maka meskipun tidak ada quiz block di halaman → counter tetap menampilkan 0 tanpa error.

Menampilkan State di HTML

Directive data-wp-text dengan State

html
<!-- Gunakan "state." bukan "context." -->
<span data-wp-text="state.solvedCount"></span>
PrefixSumberScope
context.data-wp-context di DOMLocal per block instance
state.wp_interactivity_state / storeGlobal seluruh halaman

Demo Alur Lengkap

Page Load → Counter: 0

Jawab Quiz #1 benar → state.solvedCount++ → Counter: 1

Jawab Quiz #2 benar → state.solvedCount++ → Counter: 2

Jawab Quiz #3 benar → state.solvedCount++ → Counter: 3

Semua update terjadi secara reaktif — counter otomatis update tanpa refresh!

State vs Context — Tabel Lengkap

AspekContextState
ScopePer block instanceGlobal (seluruh halaman)
Set di PHPwp_interactivity_data_wp_context()wp_interactivity_state()
Akses di JSgetContext()const { state } = store(...)
Akses di HTMLcontext.propertyNamestate.propertyName
Tempat di DOMdata-wp-context attributeTidak ada di DOM (disimpan di JS)
MergingHierarki DOM (parent → child)Namespace-based (semua block types)
Gunakan untukData block spesifikData shared antar blocks
Frekuensi~90% kasus~10% kasus

Interactivity Router (Teaser)

Belum Dirilis (Per April 2024)

WordPress sedang mengembangkan Interactivity Router — fitur terpisah yang akan membawa:

  • SPA-like navigation — berpindah halaman tanpa full page reload
  • URL management — update address bar saat navigasi
  • Browser history — tombol back/forward berfungsi
  • Mirip Next.js Link atau React Router

Fitur ini belum masuk ke core WordPress dan belum ada dokumentasi resmi. Akan dicakup di course update saat dirilis.

Ringkasan Chapter 29

Konsep Utama

KonsepPenjelasan
Interactivity APISistem resmi WP 6.5+ untuk front-end interactivity
ContextLocal state per block instance
StateGlobal state shared antar blocks
ActionsFungsi handler untuk events (click, keyup, dll.)
CallbacksFungsi yang return boolean untuk directive logic kompleks
NamespaceString penghubung antara HTML, JS store, dan PHP state

Directives yang Dipelajari

DirectiveFungsi
data-wp-interactiveAktifkan Interactivity API pada elemen (set namespace)
data-wp-contextSet local context (JSON)
data-wp-on--clickEvent handler click
data-wp-textRender teks dari context/state
data-wp-eachLoop array dari context/state
data-wp-class--[name]Toggle CSS class berdasarkan boolean
data-wp-bind--hiddenToggle attribute hidden

Fungsi PHP

FungsiKegunaan
wp_interactivity_data_wp_context($array)Convert PHP array → data-wp-context attribute
wp_interactivity_state($namespace, $array)Set global state dari PHP

Fungsi JavaScript

FungsiKegunaan
store(namespace, config)Register/akses store untuk namespace
getContext()Ambil context elemen DOM saat ini