On SwiftUI.View.onReceive(appState.objectWillChange): appState already changed: why?

Trying to find a nice way to save app state data in my SwiftUI app, using ObservableObject to hold my app data and pass one instance around using .environmentObject(). in View.onReceive(appState.objectWillChange), the data is already changed, which works out great for saving any change. But why is "WillChange" already changed?

Here this example works as expected (will change, not already changed)

Is this a good way to deal with saving app data?

import SwiftUI

// my sample app data
struct DataModel: Hashable, Codable {
    let title: String
    let when: Date
    // MARK: persistence
    static var userDefaultKey = "EventDataArchive.dat"
    static func save(list: [Self]) {
        guard let data = try? JSONEncoder().encode(list) else {
            print("JSONEncoder.encode \(Self.userDefaultKey) failed, nothing was save, you lost everything :(")
        UserDefaults.standard.set(data, forKey: Self.userDefaultKey)

    static func load() -> [Self] {
        guard let data = UserDefaults.standard.value(forKey: Self.userDefaultKey) as? Data, let list = try? JSONDecoder().decode([DataModel].self, from: data) else {
            print("Loading UserDefaults data for \(Self.userDefaultKey) key failed , returning []")
            return []
        return list

// wire this with .environmentObject() and @EnvironmentObject everywhere that can alert AppData
class AppState: ObservableObject {
    @Published var list = DataModel.load()
    func save() {
        DataModel.save(list: list)

// Some view deep inside somewhere that change app state and need to save app state
struct EditPanel: View {
    // get a hold of this to save state when data changes
    // appState.objectWillChange only fire if access this way
    @EnvironmentObject var appState: AppState
    // does not work if it's done with this:
    // @Binding var list: [DataModel]
    @State private var title = ""
    @State private var when = Date()
    var body: some View {
        VStack {
            Text("Add an Event")
            TextField("Title", text: $title)
            DatePicker(selection: $when) {
            Button("Add") {
                self.appState.list.append(DataModel(title: self.title, when: self.when))

// the root view
struct AppStateLoadSaveDemo: View {
    @ObservedObject var appState = AppState()
    static var formatter: DateFormatter {
        let result = DateFormatter()
        result.dateStyle = .medium
        result.timeStyle = .medium
        return result
    var body: some View {
        VStack {
            Button("Clear") {
                self.appState.list = []
            List {
                ForEach(self.appState.list, id: \.self) { event in
                    HStack {
                        Text(Self.formatter.string(from: event.when))
        .onReceive(appState.objectWillChange) {
            print("========== object will change ============")
            print(self.appState.list)       // <- but it's already changed!!!
            // so I can save data here?

struct AppStateLoadSaveDemo_Previews: PreviewProvider {
    static var previews: some View {