0Pricing
Swift Academy · Lección

Estado, acción y reductor

Modele las funcionalidades como reductores puros sobre el estado.

Estado, acción y reductor es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué es The Composable Architecture?

The Composable Architecture, o TCA, es una biblioteca para crear aplicaciones Swift con una estructura coherente y fácil de probar. Se centra en tres piezas: State, que describe los datos de su funcionalidad; Action, que describe todos los eventos que pueden producirse; y un Reducer, que actualiza el estado en respuesta a las acciones.

Este flujo unidireccional hace que las funcionalidades sean predecibles y fáciles de probar.

import ComposableArchitecture

// State holds data, Action describes events,
// a Reducer turns (state, action) into the next state.

La macro @Reducer

Una funcionalidad se define como un tipo anotado con la macro @Reducer. La macro genera el código auxiliar y permite declarar State, Action y el body del reducer juntos en una única unidad coherente.

Por convención, el tipo recibe el nombre de la funcionalidad, como CounterFeature.

import ComposableArchitecture

@Reducer
struct CounterFeature {
    // State, Action, and body go here
}

Definir State

State suele ser una estructura que contiene todos los datos que necesita una funcionalidad. Marcarla con @ObservableState permite que SwiftUI observe los cambios con precisión y vuelva a renderizar solo lo que se ve afectado.

Mantenga el estado mínimo y calcule los valores derivados para que exista una única fuente de verdad.

import ComposableArchitecture

@Reducer
struct CounterFeature {
    @ObservableState
    struct State: Equatable {
        var count = 0
    }
}

Definir acciones

Action es un enum que enumera todos los eventos que puede gestionar la funcionalidad: toques del usuario, respuestas, eventos del temporizador, etc. Cada caso representa algo que ha ocurrido, no una orden para mutar directamente el estado.

Los nombres claros de las acciones hacen que el comportamiento de la funcionalidad se explique por sí mismo.

import ComposableArchitecture

@Reducer
struct CounterFeature {
    @ObservableState
    struct State: Equatable { var count = 0 }

    enum Action {
        case incrementTapped
        case decrementTapped
    }
}

El body del reducer

La lógica del reducer reside en una propiedad calculada body que devuelve algún ReducerOf<Self>. Dentro de ella, use Reduce con un cierre que recibe el state mutable y la action entrante.

Use un switch sobre la acción y mute el estado según corresponda.

import ComposableArchitecture

@Reducer
struct CounterFeature {
    @ObservableState
    struct State: Equatable { var count = 0 }
    enum Action { case incrementTapped, decrementTapped }

    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .incrementTapped:
                state.count += 1
                return .none
            case .decrementTapped:
                state.count -= 1
                return .none
            }
        }
    }
}

Devolver efectos

Cada rama del reducer debe devolver un Effect. Devolver .none significa que no hay más trabajo asíncrono que realizar después del cambio de estado.

Cuando necesite efectos secundarios, como una llamada de red, devuelva un efecto que ejecute ese trabajo. Explorará los efectos en una lección posterior.

import ComposableArchitecture

// Every reducer branch returns an Effect.
// No side effect needed? Return .none.
// Need async work? Return an effect describing it.
Reduce { state, action in
    state.count += 1
    return .none
}

Las mutaciones del estado están centralizadas

Una regla fundamental de TCA es que solo el reducer modifica el estado, y únicamente en respuesta a acciones. Las vistas nunca cambian el estado directamente; envían acciones.

Este único lugar centralizado para las mutaciones hace que el flujo de datos sea fácil de seguir y de probar.

import ComposableArchitecture

// Views send actions; the reducer mutates state.
// store.send(.incrementTapped)  ->  state.count += 1
// No direct state mutation outside the reducer.

Modelar la entrada del usuario en State

Las funcionalidades similares a formularios mantienen los campos editables en State y añaden acciones para los cambios. Marcar las propiedades con bindings permite que los controles de SwiftUI las actualicen mediante acciones con seguridad de tipos.

Aquí, una funcionalidad realiza el seguimiento de un campo de texto y un interruptor.

import ComposableArchitecture

@Reducer
struct FormFeature {
    @ObservableState
    struct State: Equatable {
        var name = ""
        var isSubscribed = false
    }
    enum Action: BindableAction {
        case binding(BindingAction<State>)
    }
    var body: some ReducerOf<Self> {
        BindingReducer()
    }
}

Acciones con valores asociados

Las acciones pueden transportar datos mediante valores asociados. Así puede modelar los resultados recibidos, como un elemento cargado o un error, para que el reducer pueda almacenarlos en el estado.

Aquí, una acción de respuesta transporta el número obtenido.

import ComposableArchitecture

@Reducer
struct NumberFeature {
    @ObservableState
    struct State: Equatable { var value = 0 }
    enum Action {
        case reloadTapped
        case responseReceived(Int)
    }
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .reloadTapped:
                return .none
            case let .responseReceived(value):
                state.value = value
                return .none
            }
        }
    }
}

Por qué ayuda que State sea Equatable

Hacer que State cumpla Equatable permite que TCA detecte si el estado realmente ha cambiado, lo que permite actualizar las vistas con precisión y realizar pruebas exhaustivas. Es un pequeño requisito con grandes beneficios.

La mayoría de los tipos de estado adoptan Equatable automáticamente porque sus propiedades almacenadas ya lo cumplen.

import ComposableArchitecture

@ObservableState
struct State: Equatable {
    var count = 0
    var title = ""
}
// Equatable enables change detection and test assertions.

La estructura de una funcionalidad completa

Una funcionalidad terminada se lee de arriba abajo: la macro, el estado observable, el enum de acciones y el body del reducer. Todo lo relacionado con la funcionalidad vive en un único tipo, lo que hace que las funcionalidades de TCA sean componibles y fáciles de revisar.

Esta estructura coherente se repite en todas las funcionalidades de una aplicación.

import ComposableArchitecture

@Reducer
struct CounterFeature {
    @ObservableState
    struct State: Equatable { var count = 0 }
    enum Action { case incrementTapped, decrementTapped }
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .incrementTapped: state.count += 1; return .none
            case .decrementTapped: state.count -= 1; return .none
            }
        }
    }
}

Comprobación rápida: las tres piezas

Recuerde las funciones de State, Action y el Reducer en TCA.

Resumen: State, Action y Reducer

Ha aprendido los elementos centrales de una funcionalidad de TCA:

  • @Reducer define un tipo de funcionalidad que contiene todo en un único lugar.
  • @ObservableState en una estructura contiene los datos de la funcionalidad y permite observarlos con precisión.
  • Un enum Action enumera todos los eventos, opcionalmente con valores asociados.
  • El body del reducer usa Reduce para mutar el estado y devolver un Effect, con .none cuando no se necesita ningún efecto secundario.
  • Solo el reducer modifica el estado, lo que mantiene el flujo de datos predecible.

A continuación, conectará esta funcionalidad con SwiftUI mediante un Store.

import ComposableArchitecture

// Recap: @Reducer + State + Action + body(Reduce)
// One type, one source of truth, predictable updates.

Preguntas frecuentes

¿La lección «Estado, acción y reductor» es gratis?

Sí — el texto completo de «Estado, acción y reductor» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Estado, acción y reductor»?

Modele las funcionalidades como reductores puros sobre el estado. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Estado, acción y reductor»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Estado, acción y reductor
  2. El Store e integración con SwiftUI
  3. Efectos y dependencias
  4. Composición y pruebas de funcionalidades
← Volver a Swift Academy