Skip to content

Updating State of Mapped Arrays

State becomes truly useful when you modify it based on user actions, like clicking a button. This is done using the client-side setState() function.

Two Approaches

You can update state in two primary ways: a quick inline method for simple changes, and a more robust script-based method for complex logic.

The Direct Way: Inline Updates

For simple actions like adding a new item to a list, you can call setState() directly within an HTML attribute like onclick.

This approach uses the JavaScript spread syntax (...) to create a new array that includes all the old items plus the new one.

<?php
use function Component\useState;

function TodoList() {
   $todos = useState('todos', [
      ['id' => 1, 'text' => 'Learn phpspa'],
   ]);

   $newId = count($todos()) + 1;

   return <<<HTML
      <div>
         <h3>My To-Do List</h3>
         <ul>
            {$todos->map(fn($item) => "<li>{$item['text']}</li>")}
         </ul>

         <button onclick='setState("todos", [...{$todos}, { id: {$newId}, text: "A new task" }])'>
            Add Todo
         </button>
      </div>
   HTML;
}

Spread Syntax

This approach uses the JavaScript spread syntax (...) to create a new array that includes all the old items plus the new one.

The Customizable Way: Using a Script

When your update logic is more complex (e.g., reading from input fields), it's cleaner to use a dedicated JavaScript function.

First, pass your initial state to a JavaScript variable. Then, you can manipulate this variable with standard JavaScript before calling setState() with the final data.

<?php
use function Component\useState;

function TodoList() {
   $todos = useState('todos', [
      ['id' => 1, 'text' => 'Learn phpspa'],
   ]);

   return <<<HTML
      <div>
         <h3>My To-Do List</h3>
         <ul id="todo-list-ul">
            {$todos->map(fn($item) => "<li>{$item['text']}</li>")}
         </ul>

         <button onclick="addTodo()">Add Todo</button>
      </div>

      <script>
         // Get the initial state from PHP
         let todosData = {$todos};

         function addTodo() {
            // Perform any logic you need in JavaScript
            let newId = todosData.length + 1;
            todosData.push({ id: newId, text: 'New task ' + newId });

            // Update the state with the modified array
            setState('todos', todosData);
         }
      </script>
   HTML;
}

Complex Logic

First, pass your initial state to a JavaScript variable. Then, you can manipulate this variable with standard JavaScript before calling setState() with the final data.