Swift Academy · บทเรียน

Store และการผสานกับ SwiftUI

ขับเคลื่อนมุมมองจาก Store ของ TCA

บทเรียน 2 จาก 413 ขั้นตอน

Store และการผสานกับ SwiftUI เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

คลังสถานะคืออะไร

คลังสถานะ คือออบเจ็กต์ขณะทำงานที่เก็บสถานะของฟีเจอร์และเรียกใช้รีดิวเซอร์ มุมมอง SwiftUI จะสังเกตคลังสถานะเพื่ออ่านสถานะ และส่งการกระทำไปยังคลังสถานะเพื่อกระตุ้นการเปลี่ยนแปลง

คลังสถานะเป็นสะพานเชื่อมระหว่างตรรกะรีดิวเซอร์บริสุทธิ์กับส่วนติดต่อผู้ใช้ที่ทำงานและโต้ตอบได้จริง

import ComposableArchitecture
import SwiftUI

// A Store holds State, runs the Reducer,
// and is observed by SwiftUI views.

นามแฝงชนิด StoreOf

StoreOf<Feature> เป็นนามแฝงที่สะดวกสำหรับคลังสถานะซึ่งกำหนดให้ใช้กับชนิดสถานะและชนิดการกระทำของฟีเจอร์หนึ่งโดยเฉพาะ โดยทั่วไปมุมมองจะเก็บคลังสถานะดังกล่าวไว้เป็นพร็อพเพอร์ตี

ดังนั้น มุมมองตัวนับจึงเก็บ StoreOf<CounterFeature>

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        Text("Count: \(store.count)")
    }
}

การสร้างคลังสถานะ

คุณสร้างคลังสถานะด้วยตัวเริ่มต้น Store โดยระบุสถานะเริ่มต้นและรีดิวเซอร์ที่จะเรียกใช้ โดยทั่วไปจะทำเพียงครั้งเดียวใกล้กับจุดเริ่มต้นของแอป

โคลเชอร์ต่อท้ายจะส่งคืนอินสแตนซ์ของฟีเจอร์ของคุณ

import ComposableArchitecture
import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            CounterView(
                store: Store(initialState: CounterFeature.State()) {
                    CounterFeature()
                }
            )
        }
    }
}

การอ่านสถานะโดยตรง

ด้วยการสังเกตแบบสมัยใหม่ มุมมองจะอ่านสถานะจากคลังสถานะโดยตรงผ่านไวยากรณ์จุด เช่น store.count เนื่องจากสถานะเป็น @ObservableState SwiftUI จึงแสดงผลใหม่เฉพาะส่วนที่ขึ้นอยู่กับค่าที่เปลี่ยนแปลง

การอ่านค่าแบบง่าย ๆ ไม่จำเป็นต้องใช้ตัวห่อเพิ่มเติม

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        VStack {
            Text("Count: \(store.count)")
        }
    }
}

การส่งการกระทำ

หากต้องการเปลี่ยนสถานะ มุมมองจะส่งการกระทำด้วย store.send(.someAction) คลังสถานะจะส่งต่อการกระทำให้รีดิวเซอร์ ซึ่งจะเปลี่ยนสถานะและอาจเริ่มเอฟเฟกต์

ในที่นี้ ปุ่มจะส่งการกระทำเพิ่มค่าและลดค่า

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        HStack {
            Button("-") { store.send(.decrementTapped) }
            Text("\(store.count)")
            Button("+") { store.send(.incrementTapped) }
        }
    }
}

การผูกข้อมูลจากคลังสถานะ

สำหรับตัวควบคุมของ SwiftUI ที่ต้องใช้การผูกข้อมูลแบบสองทาง TCA ช่วยให้คุณสร้าง Binding จากคลังสถานะได้เมื่อสถานะใช้การกระทำที่รองรับการผูกข้อมูล ตัวควบคุมจะอัปเดตสถานะโดยส่งการกระทำแบบผูกข้อมูล

ในที่นี้ TextField จะผูกกับช่องชื่อ

import ComposableArchitecture
import SwiftUI

struct FormView: View {
    @Bindable var store: StoreOf<FormFeature>
    var body: some View {
        TextField("Name", text: $store.name)
    }
}

WithViewStore แบบเดิม

ก่อนมีการสังเกต มุมมองจะห่อส่วนติดต่อผู้ใช้ด้วย WithViewStore เพื่ออ่านสถานะและรับ viewStore สำหรับส่งการกระทำ คุณจะยังพบรูปแบบนี้ในโค้ดเก่า

โคลเชอร์ observe จะเลือกว่าสถานะส่วนใดเป็นสิ่งที่มุมมองต้องใช้

import ComposableArchitecture
import SwiftUI

struct LegacyCounter: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        WithViewStore(store, observe: { $0 }) { viewStore in
            Text("Count: \(viewStore.count)")
        }
    }
}

การเลือกสิ่งที่จะสังเกต

ในรูปแบบเดิม โคลเชอร์ observe จะจำกัดสถานะที่มุมมองเฝ้าดูให้แคบลง มุมมองจึงแสดงผลใหม่เฉพาะเมื่อค่าเหล่านั้นเปลี่ยนแปลง การสังเกตสถานะทั้งหมดเป็นวิธีที่ง่ายที่สุด ส่วนการสังเกตเพียงบางส่วนช่วยเพิ่มประสิทธิภาพให้มุมมองขนาดใหญ่

@ObservableState สมัยใหม่จะจัดการเรื่องนี้โดยอัตโนมัติ แต่การเข้าใจ observe จะช่วยเมื่อคุณอ่านโค้ดเก่า

import ComposableArchitecture
import SwiftUI

// Observe just the count to limit re-renders:
WithViewStore(store, observe: { $0.count }) { viewStore in
    Text("\(viewStore)")
}

การส่งการกระทำพร้อมข้อมูลประกอบ

การกระทำที่มีค่าที่เชื่อมโยงจะถูกส่งโดยระบุค่านั้น วิธีนี้ทำให้มุมมองส่งต่อข้อมูลที่ผู้ใช้ป้อนซึ่งรีดิวเซอร์ต้องใช้ได้

ในที่นี้ การเลือกแถวจะส่งรหัสที่เลือก

import ComposableArchitecture
import SwiftUI

struct ListView: View {
    let store: StoreOf<ListFeature>
    var body: some View {
        Button("Pick 42") {
            store.send(.rowSelected(id: 42))
        }
    }
}

การทำให้การกระทำมีภาพเคลื่อนไหว

คุณสามารถแนบภาพเคลื่อนไหวไปกับการกระทำที่ส่ง เพื่อให้การเปลี่ยนสถานะที่เกิดขึ้นมีภาพเคลื่อนไหว โดยส่งอาร์กิวเมนต์ animation ให้กับ send

วิธีนี้ทำให้จัดการเรื่องภาพเคลื่อนไหวที่จุดเรียกใช้ได้ โดยสถานะยังคงเป็นข้อมูลธรรมดา

import ComposableArchitecture
import SwiftUI

Button("Toggle") {
    store.send(.toggleTapped, animation: .default)
}

การประกอบมุมมอง

มุมมอง TCA ที่สมบูรณ์จะเก็บ StoreOf อ่านสถานะด้วยไวยากรณ์จุด และส่งการกระทำจากตัวควบคุม รีดิวเซอร์จะจัดการส่วนที่เหลือ ทำให้มุมมองกระชับและเป็นเชิงประกาศ

การแยกส่วนเช่นนี้ทำให้มุมมอง TCA อ่านและดูตัวอย่างได้ง่าย

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        VStack {
            Text("Count: \(store.count)")
            Button("Increment") { store.send(.incrementTapped) }
        }
    }
}

ตรวจสอบความเข้าใจ: การควบคุมส่วนติดต่อผู้ใช้

ทบทวนว่ามุมมอง SwiftUI กระตุ้นการเปลี่ยนสถานะใน TCA ได้อย่างไร

ทบทวน: คลังสถานะและ SwiftUI

คุณได้เชื่อมต่อฟีเจอร์กับ SwiftUI แล้ว:

  • StoreOf<Feature> เก็บสถานะและเรียกใช้รีดิวเซอร์
  • คุณสร้างคลังสถานะด้วยสถานะเริ่มต้นและรีดิวเซอร์ของฟีเจอร์
  • การสังเกตแบบสมัยใหม่ทำให้คุณอ่านสถานะด้วยไวยากรณ์จุด เช่น store.count
  • มุมมองเปลี่ยนสถานะโดยเรียก store.send(.action) และอาจส่งข้อมูลประกอบหรือภาพเคลื่อนไหวไปด้วย
  • WithViewStore แบบเดิมและโคลเชอร์ observe จะพบในโค้ดเก่า

ถัดไป คุณจะเพิ่มผลข้างเคียงและการพึ่งพาที่ฉีดเข้าได้ให้รีดิวเซอร์

import ComposableArchitecture
import SwiftUI

// Recap: StoreOf holds state, view reads with dot syntax,
// store.send(.action) drives every change.
เริ่มต้นได้ฟรี

เรียนรู้ Swift ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
122
บทเรียน
409

คำถามที่พบบ่อย

บทเรียน “Store และการผสานกับ SwiftUI” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Store และการผสานกับ SwiftUI” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Store และการผสานกับ SwiftUI”

ขับเคลื่อนมุมมองจาก Store ของ TCA คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “Store และการผสานกับ SwiftUI” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. สถานะ แอ็กชัน และรีดิวเซอร์
  2. Store และการผสานกับ SwiftUI
  3. เอฟเฟกต์และการพึ่งพา
  4. การประกอบและทดสอบความสามารถ
← กลับไปที่ Swift Academy