Каков наилучший способ двусторонней привязки компонента пользовательского интерфейса к наблюдаемому для уменьшения рендеринга?

Мы создаем приложение MVVM с помощью mobx и реагируем. В настоящее время лучше всего создавать модели представления и компоненты пользовательского интерфейса, подобные этому упрощенному примеру.

// LoginModel.ts
export class LoginModel {
  @observable
  public userName: string;
  
  @observable
  public password: string;
}

// LoginView.tsx
@observer
export class LoginView extends React.Component<LoginViewProps> {

  public render(): JSX.Element {
    return (
      <div>
        <input type="text" value={this.model.userName} onChange={e => this.model.userName = e.value} />        
        <input type="password" value={this.model.password} onChange={e => this.model.password= e.value} />
      </div>
    );
  }

}

AFAIK в этой реализации компонент будет полностью перерисован при изменении userName или password.

Чего я бы хотел добиться, так это иметь наш собственный компонент TextInput, который будет отвечать за рендеринг макета, стили, получение пользовательского ввода, а также для отображения ошибок проверки на основе состояния модели и т. Д. Прямо сейчас я вижу два варианта.

  1. Раскройте value, onChange и, например, error в пользовательском компоненте и используйте его так же, как в примере выше. В этом случае проблема та же, каждое изменение в одном наблюдаемом свойстве AFAIK будет повторно отображать весь компонент формы. Это связано с тем, что я не разыменую наблюдаемое в компоненте TextInput, а в LoginView.
  2. Выставьте что-то вроде model: any и field: string и используйте model[field] внутри. Таким образом, я бы сделал разыменование внутри TextInput, и это могло бы работать нормально, НО я бы потерял некоторую строгую типизацию и универсальность.

Несколько примечаний:

  • При первом запуске я намеренно не хотел бы использовать такие библиотеки, как react-forms и т. Д.
  • Кроме того, если кто-то это заметит, я намеренно не хотел бы использовать паттерны Provider и @inject, мне нравится быть явным.

Может ли кто-нибудь дать мне несколько идей и предложений по такому сценарию?


person Zoltán Tamási    schedule 06.07.2020    source источник


Ответы (1)


Существует отличная библиотека форм для mobx, в которой используется очень похожая техника https://formstate.github.io, вы наверное можно скопировать с него этот узор.

person Danila    schedule 06.07.2020