---
# System prepended metadata

title: State、Binding、Environment 介紹
tags: [SwiftUI]

---

---
title: 'State、Binding、Environment 介紹'
tags: SwiftUI
disqus: hackmd
---

**目錄：**

[TOC]

## State<Value>
* 用來儲存和觀察一個Value Type的變化
    `在SwiftUI中，View是Struct，然後畫面是在它的計算屬性body裡面產生，我們沒有辦法在計算屬性裡面去修改自己的值，所以我們才要把想要改變的值存在另一個地方，而State就是在幫我們做這件事。`
    `把資料存在另一個地方管理，並且在值改變時，自動通知畫面進行更新`
    
* thread-safe
    `不用擔心在不同線程修改它的問題`
    
* <font color="#f00">State 不該被用任何形式傳遞</font>
    `要確保State只屬於被建立的那個View，不可以有其他任何地方能夠存取到這個State本身`
    `這是為了可以讓SwiftUI可以正確的幫你管理這個值，讓這個State的生命週期跟著這個畫面`
    
    1.設定private，避免由外部啟動。
    2.不使用底線版本的屬性。
    
* Projected value是Binding<value>
    `直接連接到State裡面的Value，所以對外部來說只知道這個Value，並不會知道這個State的存在`
    
## Binding<Value>
* 包含兩個closure:
    
      set: (Value) -> Void
      get: () -> Value
    
    看到上面兩個closure，就會知道Binding是<font color="#f00">可以被傳來傳去的計算屬性</font>
    
* 通常用來傳遞對一個Value Type資料修改的方法
    
* Projected value是自己，也就是Binding<Value>

    ---
    <font color="#f00">Binding與畫面更新無關</font>
    <font color="#2894FF">State應放在需要存取值的最上層</font>

## Environment<Value>

* 用來讀取一些系統在APP啟動時變建立的『環境變數』
    `例如：字體大小、顏色模式`
    
* 這些環境變數被改動時，關聯的畫面都會一起更新
    
* 只能讀取(get)，不能寫入(set)
    `如果想要修改它，只能用.environment(\.colorScheme, .dark)這個調整器`
    `但它也不是真的去修改原本的環境變數，它只是在後面把它覆蓋掉`
    `那它會影響的就是這個畫面以下的地方`
    
* 啟動方式是放入一個EnviromentValues的KeyPath
    `可以去EnviromentValues的文件上看，有哪些環境變數可以用`
    