@State

SwiftUI로 뷰를 만들고, 변수의 값이 바뀌면 뷰의 내용도 그에 따라 업데이트하고 싶을 때 처음 마주하는 키워드가 @State 일 것이다. 나 역시 무작정 투두 리스트 만들기를 할 때 텍스트 필드 뷰에 연결된 변수가 바뀔 때마다 뷰가 업데이트되길 바라며 해당 키워드를 사용했다.

@State의 용례만 봐도 이 친구가 뷰를 리로드해주는 특별한 변수라는 것을 알 수 있다. 공식 문서 에 쓰여진 State의 개요를 보면, ‘State 값이 변경되면, 뷰는 바디를 다시 연산하여 그 모습을 바꾼다’고 되어 있다. 즉, @State로 선언한 변수는 값이 변경될 때마다 해당 뷰의 모습을 새로고침하는 것이다.

Property Wrapper

프로퍼티 래퍼는 프로퍼티의 get/set 코드가 여러 프로퍼티에서 중복되어 사용될 때, 이를 특정한 키워드로 정의해 가져다 쓸 수 있게 하는 것이다. 정의하고자 하는 클래스, 구조체, enum 등의 앞에 @propertyWrapper 를 써 주면, 정의된 클래스, 구조체, enum 등을 프로퍼티 래퍼로 사용할 수 있다.

공식 문서에 정의된 State는 ‘A Property Wrapper Type’ 이라고 한다.

@frozen @propertyWrapper struct State<Value>

실제로 정의된 부분을 보면 @propertyWrapper 키워드가 사용된 것을 알 수 있다.

내부적으로 어떻게 구현돼있는지 확인하지 못했지만, 뷰의 상태를 변경 해 주는 로직이 State 구조체에 담겨 있지 않을까 하는 생각이 든다.

Private

공식 문서에 이런 구절이 적혀 있다. ‘You should only access a state property from inside the view’s body, or from methods called by it.’

State 프로퍼티를 뷰의 바디 내부나 이를 통해 호출되는 메서드에서만 접근할 수 있어야 한다는 말인데, State가 영향을 미치는 범위를 생각 해 보면 이 말을 이해할 수 있다. 뷰 내부에서 사용되어 해당 뷰의 모습을 업데이트하기 때문에, 이를 뷰 바깥에서 사용할 순 없는 노릇이다.

그래서 @State 를 사용해 변수를 선언할 땐, private 키워드를 함께 쓰도록 권장하고 있다.

projectedValue

내가 @State 키워드를 처음 사용하게 된 것은 앞에서도 말했듯 TextField를 통해 값을 입력받고 이 내용을 뷰에 업데이트할 때다. 이 때 나는 State 뿐만 아니라 $가 붙는 이상한 색다른 친구를 만났다. 속성을 보니 Binding이라고 적혀 있었고, 이를 검색 해 보니 뷰 끼리 연결해 변수를 주고받을 때 사용한다는 것을 알게 되었다.

텍스트 필드에 값을 입력하고, 이를 통해 뷰를 업데이트하고자 할 때, 나는 @State$를 모두 사용했다. 다른 뷰에서 변수에 접근할 수 있도록 $ 키워드로 변수를 바인딩하고, 해당 변수가 변경됨에 따라 뷰가 업데이트될 수 있도록 그 변수를 @State 로 정의했다. 이렇게 State 값을 바인딩하는 것을 projectedValue 라고 한다.

결론

변수를 하나 두어 이를 변경함에 따라 뷰를 리로드하려면 @State 라는 프로퍼티 래퍼를 사용하면 된다.

이는 뷰 내부적으로 혹은 뷰 안의 메서드에 의해서만 변경되기 때문에, private 키워드로 그 사용 범위를 제한하며, String이나 Bool, Int와 같이 단일 뷰에서 사용할 수 있는 기본적인 타입의 변수로 주로 사용된다.

복수 뷰에서 State 변수를 사용하고자 한다면, $ 로 바인딩해서 사용하자.

잘못된 부분이나 추가할 사항이 있다면 언제든 말해주세요!

댓글남기기