---
title: "Estado y eventos en React"
slug: "react-state-events"
category: "Patterns"
hosts: "react"
locale: "es"
reactExample: "recipe-status.tsx"
---

# Estado y eventos en React

Los widgets reciben su configuración por `data`. La selección, los datos de formulario, los permisos y los registros guardados los gestionas en React o en tu store.

## Un flujo de datos controlado

1. Deriva el objeto `data` de tu estado actual.
2. Recibe la entrada por el callback concreto.
3. Valídala y, si hace falta, guárdala con tu API.
4. Sustituye en el estado los objetos y arrays afectados.

No mutes objetos que hayas pasado. Los índices de UI no son IDs de registro: resuélvelos contra la lista actual antes de guardar.

## Nombres de callback y fallback

Cada referencia describe argumentos y flags de activación. Table necesita `clickable: true` para clics en celdas; Steps lo necesita por paso.

`onAction(type, ...args)` recibe el nombre interno del evento y sus argumentos. Un callback concreto, por ejemplo `onCellClick`, tiene prioridad. Para el mismo evento no se ejecutan ambos handlers. `onAction` no es un objeto de acción ni una llamada automática a la API.

## Guardado asíncrono

Con el indicador de carga activado, Button espera la promesa que devuelve `onClick`. Kanban mantiene el drop abierto con `onItemDrop`; si se rechaza, el adaptador deshace el movimiento optimista. Estas garantías son específicas del widget y no aplican automáticamente a cada callback.

Captura los errores donde puedas mostrar un mensaje a las personas usuarias. En Kanban, relanza el error después para que el adaptador aborte el movimiento.

```tsx
import { useState } from 'react';
import { ArcWidgetButton, ArcWidgetBadge } from '@arcrider/arcwidgets-react';
export default function Example() {
  const [status, setStatus] = useState('Offen');
  const [error, setError] = useState('');
  async function save(next: string) {
    try {
      localStorage.setItem('arc-demo-status', next);
      setStatus(next);
      setError('');
    } catch {
      setError(
        'Status konnte nicht gespeichert werden. Bitte erneut versuchen.',
      );
    }
  }
  return (
    <>
      <ArcWidgetBadge
        data={{
          value: status,
        }}
      />
      <div
        style={{
          display: 'flex',
          gap: 12,
        }}
      >
        {['Offen', 'In Arbeit', 'Erledigt'].map((label) => (
          <ArcWidgetButton
            key={label}
            data={{
              title: label,
              width: '140px',
              loading: {
                show: true,
              },
            }}
            onClick={() => save(label)}
          />
        ))}
      </div>
      <p role="status">{error || 'Änderungen werden lokal gespeichert.'}</p>
    </>
  );
}
```

## Acceso a datos

Los ejemplos se ejecutan por completo con datos locales. `localStorage` queda limitado al navegador y al dominio. Para datos compartidos, sustituye esa parte por tu API; el control de acceso, la carga y los conflictos los trata tu aplicación.

Para filtros de lista: lista de pedidos. Para arrastrar y soltar: guardar Kanban.
