Как реактивно использовать ноду-простую схему?

Учитывая, что примеров по этому поводу немного, я следую за документами настолько хорошо, насколько могу, но проверка не является реактивной.

Я объявляю схему:

import { Tracker } from 'meteor/tracker';
import SimpleSchema from 'simpl-schema';

export const modelSchema = new SimpleSchema({
  foo: { 
    type: String,
    custom() {
      setTimeout(() => {
        this.addValidationErrors([{ name: 'foo', type: 'notUnique' }]);
      }, 100);  // simulate async
      return false;
    }
  }
}, {
  tracker: Tracker
});

Затем я использую эту схему в моем компоненте:

export default class InventoryItemForm extends TrackerReact(Component) {

  constructor(props) {
    super(props);

    this.validation = modelSchema.newContext();
    this.state = {
      isValid: this.validation.isValid()
    };
  }

  ...

  render() {
    ...
    const errors = this.validation._validationErrors;

    return (
      ...
    )
  }
}

Поэтому всякий раз, когда я пытаюсь проверить fooвызывается асинхронная пользовательская функция, а addValidationErrors функция вызывается, но компонент никогда не перерисовывается, когда this.validation.isValid() должен быть ложным.

Что мне не хватает?

1 ответ

Решение

На самом деле в вашем коде есть две ошибки. во-первых this.addValidationErrors не может использоваться асинхронно внутри пользовательской проверки, так как это не относится к правильному контексту проверки. Во-вторых, TrackerReact регистрирует только реактивные источники данных (такие как .isValid) внутри render функция, поэтому недостаточно только доступа _validationErrors в этом. Таким образом, чтобы заставить его работать, вам нужно использовать именованный контекст проверки и вызвать isValid в функции рендеринга (или другой вызываемой ею функции), например:

в валидации

custom() {
  setTimeout(() => {
    modelSchema.namedContext().addValidationErrors([
      { name: 'foo', type: 'notUnique' }
    ]);
  }, 100);
}

компонент

export default class InventoryItemForm extends TrackerReact(Component) {
  constructor(props) {
    super(props);

    this.validation = modelSchema.namedContext();
  }

  render() {
    let errors = [];
    if (!this.validation.isValid()) {
      errors = this.validation._validationErrors;
    }

    return (
      ...
    )
  }
}

Подробнее об асинхронной проверке смотрите здесь.

Другие вопросы по тегам