DeveloPiano

[SwiftUI] 상태 관리: @State, @Binding, @StateObject, 그리고 @EnvironmentObject 본문

Develop/SwiftUI

[SwiftUI] 상태 관리: @State, @Binding, @StateObject, 그리고 @EnvironmentObject

DevPi 2024. 7. 16. 20:00
반응형

SwiftUI에서 상태 관리는 애플리케이션의 데이터 흐름과 뷰 업데이트를 효과적으로 처리하는 데 중요한 역할을 합니다. 올바른 상태 관리 도구를 사용하는 것은 코드의 가독성과 유지보수성을 높이는 데 필수적입니다.

이번에는 @State, @Binding, @StateObject, 그리고 @EnvironmentObject의 사용 방법과 적절한 사용 시점을 다루겠습니다.


@State와 @Binding

@State

@State는 SwiftUI에서 뷰의 내부 상태를 관리하는 데 사용됩니다. 이 상태는 해당 뷰 내에서만 사용되며, 상태가 변경될 때마다 뷰가 자동으로 다시 렌더링됩니다.

struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button(action: {
                count += 1
            }) {
                Text("Increment")
            }
        }
    }
}

위 예시에서 count는 @State로 선언되어, 버튼을 클릭할 때마다 값이 증가하고 텍스트가 업데이트됩니다.

 

@Binding

@Binding은 부모 뷰의 상태를 자식 뷰로 전달하여, 자식 뷰에서 그 상태를 읽고 수정할 수 있게 합니다. 이는 두 개의 뷰 사이에서 값을 전달할 때 사용됩니다.

struct ParentView: View {
    @State private var text: String = "Hello"

    var body: some View {
        VStack {
            Text("Parent View: \(text)")
            ChildView(text: $text)
        }
    }
}

struct ChildView: View {
    @Binding var text: String

    var body: some View {
        TextField("Enter text", text: $text)
    }
}

위 예시에서 text는 ParentView의 @State로 관리되며, ChildView에 @Binding으로 전달됩니다. 이를 통해 ChildView에서 text 값을 읽고 수정할 수 있습니다.


@StateObject와 @EnvironmentObject

@StateObject

@StateObject는 뷰 모델 객체를 생성하고 소유할 때 사용됩니다. 데이터의 생명 주기를 해당 뷰가 관리합니다. 주로 최상위 뷰 또는 소유 뷰에서 사용됩니다.

 

@EnvironmentObject

@EnvironmentObject는 상위 뷰에서 제공된 객체를 하위 뷰들에서 사용할 수 있게 합니다. 여러 뷰에서 동일한 데이터에 접근하고 변경할 때 사용됩니다. @StateObject와 함께 사용하여 데이터의 생명 주기를 관리하면서 여러 뷰에 걸쳐 데이터를 공유할 수 있습니다.

 

먼저, 공유할 데이터를 관리하는 클래스를 만듭니다.

import SwiftUI
import Combine

class SharedData: ObservableObject {
    @Published var value: String = "Initial Value"
}

 

ParentView에서 SharedData 인스턴스를 생성하고 NavigationView를 설정합니다.

struct ParentView: View {
    @StateObject private var sharedData = SharedData()

    var body: some View {
        NavigationView {
            VStack {
                Text("Parent View")
                Text("Shared Value: \(sharedData.value)")
                NavigationLink(destination: FirstChildView()) {
                    Text("Go to First Child View")
                }
                NavigationLink(destination: SecondChildView()) {
                    Text("Go to Second Child View")
                }
            }
            .environmentObject(sharedData)
        }
    }
}

 

FirstChildView에서 @EnvironmentObject를 사용하여 공유 데이터를 접근하고 값을 변경합니다.

struct FirstChildView: View {
    @EnvironmentObject var sharedData: SharedData

    var body: some View {
        VStack {
            Text("First Child View")
            Text("Shared Value: \(sharedData.value)")
            Button(action: {
                sharedData.value = "Changed by First Child"
            }) {
                Text("Change Value")
            }
        }
    }
}

 

SecondChildView에서도 @EnvironmentObject를 사용하여 공유 데이터를 접근합니다.

struct SecondChildView: View {
    @EnvironmentObject var sharedData: SharedData

    var body: some View {
        VStack {
            Text("Second Child View")
            Text("Shared Value: \(sharedData.value)")
        }
    }
}

요약

  • @State와 @Binding: 두 개의 뷰 사이에서 데이터를 전달하고 공유할 때 사용합니다.
  • @StateObject와 @EnvironmentObject: 여러 뷰에서 데이터를 공유하고 관리할 때 사용합니다.

이 접근 방식을 통해 SwiftUI 애플리케이션에서 상태와 데이터를 효과적으로 관리하고, 코드의 가독성과 유지보수성을 높일 수 있습니다. 올바른 상태 관리 도구를 선택하여 더 나은 SwiftUI 애플리케이션을 개발해볼 수 있습니다.

반응형