Unexpected Behavior on Validations using Bindings with TextField

I am having trouble getting TextField to display the same string as what is in my store. The proper value is being reflected on the TextView, i.e, every time I go beyond 10 digits it stays 10 digits, however the TextField retains more than 10 digits. The next time I enter a new value, it continues to send the entire number that is longer than 10 digits into the store.

This is my view:

    @Bindable var store: StoreOf<SomeInputReducer>
    private var someTextView: some View {
        Text(store.number)
            .fontWeight(.black)
            .modifier(RoundedBorder())
    }
    
    private var numberField: some View {
        TextField("", text: $store.number)
            .fontWeight(.black)
            .modifier(RoundedBorder())
            .keyboardType(.numberPad)
    }

This is my reducer:

@Reducer
public struct SomeInputReducer {
    
    public init() {}
    
    @ObservableState
    public struct State: Equatable {
        public init(number: String = "") {
            self.number = number
        }
        var number: String
    }
    
    public enum Action: BindableAction, Equatable {
        case binding(BindingAction<State>)
    }
    
    public var body: some ReducerOf<Self> {
        BindingReducer()
            .onChange(of: \.number) { oldValue, newValue in
                Reduce { state, action in
                    if newValue.count > 10 {
                        state.number = String(newValue.prefix(10))
                    }
                    return .none
                }
            }
        Reduce { state, action in
            switch action {
            case .binding:
                return .none
            }
        }

    }
}

Hi @varunadit, this is just an issue with SwiftUI in general. You can reproduce the problem with vanilla SwiftUI using an @Observable model:

@Observable
class Model {
  var text: String = "" {
    didSet {
      guard text.count > 10
      else { return }
      text = String(text.prefix(10))
    }
  }
}
struct FeatureView: View {
  @State var model = Model()
  var body: some View {
    Form {
      TextField("Text", text: $model.text)
    }
  }
}
#Preview {
  FeatureView()
}

One way to fix is to use @State for the text, but even then if you type fast enough you will see little glitches of extra characters show in the view:

struct FeatureView: View {
  @State var text = ""
  var body: some View {
    Form {
      TextField("Text", text: $text)
    }
    .onChange(of: text) {
      guard text.count > 10
      else { return }
      text = String(text.prefix(10))
    }
  }
}
#Preview {
  FeatureView()
}