# SwiftUI: the Button view and updating the app state

> Learn how to use the Button view in SwiftUI to run an action when tapped, and why you need the @State property wrapper to update your app's state.

Author: Flavio Copes | Published: 2021-09-18 | Canonical: https://flaviocopes.com/swiftui-button-view/

The `Button` view can be used to display an interactive button element.

We can declare it in this way:

```swift
Button("Button label") {
    //this happens when it's tapped
}
```

Or in this way:

```swift
Button {
   //this happens when it's tapped
} label: {
   Text("Button label")
}
```

This second way is more common when you have something else as the label of the button, not text. For example an image.

Let's use the first way in a [SwiftUI](https://flaviocopes.com/swiftui-introduction/) program:

```swift
struct ContentView: View {
    var body: some View {
        Button("Test") {
            
        }
        .font(.title)
    }
}
```

See? There is a blue text in the app, and you can tap it. It's interactive.

![Xcode showing SwiftUI Button code and iPhone simulator displaying a blue Test button](https://flaviocopes.com/images/swiftui-button-view/Screen_Shot_2021-09-13_at_15.33.01.png)

We haven't told it to do anything when tapped, so it does anything.

We can print something to the debugging console:

```swift
struct ContentView: View {
    var body: some View {
        Button("Test") {
            print("test")
        }
        .font(.title)
    }
}
```

> Note that this works only when you run the app, not in the Xcode preview

Now we can add another step to our app. We'll print a property value inside the button label:

```swift
struct ContentView: View {
    var count = 0
    
    var body: some View {
        Button("Count: \(count)") {
            
        }
        .font(.title)
    }
}
```

And when it's clicked we increment the count:

```swift
struct ContentView: View {
    var count = 0
    
    var body: some View {
        Button("Count: \(count)") {
            self.count += 1
        }
        .font(.title)
    }
}
```

But the app will not compile, with the error

> `Left side of mutating operator isn't mutable: 'self' is immutable` ❌

We need to use the `@State` property wrapper before we declare the property:

```swift
struct ContentView: View {
    @State var count = 0
    
    var body: some View {
        Button("Count: \(count)") {
            self.count += 1
        }
        .font(.title)
    }
}
```

The app will now work and we can click the label to increment the `count` property value:

![Xcode showing SwiftUI @State count code and iPhone simulator displaying Count: 6 button](https://flaviocopes.com/images/swiftui-button-view/Screen_Shot_2021-09-13_at_15.39.44.png)

Of course the counter will start from 0 the next time we run it, because we are not persisting the state in any way. We'll get to that later.
