React.js joi-browser 根据数据库验证

React.js joi-browser validate according to database

我正在尝试使用“joi-browser”模式验证输入。 我希望输入值只有在与处于该状态的数组内的任何一个对象内的描述 属性 相似时才有效。 该数组来自数据库,并设置在 componentDidMount.

目前架构是这样的:

orderItemsSchema = {
  id: Joi.number(),
  description: Joi.string().min(6).max(30).label("Description"),
  quantity: Joi.number().min(1).label("Quantity"),
};

schema = {
  custName: Joi.string().min(2).max(30).required().label("Customer Name"),
  orderItems: Joi.array()
    .label("orderItems")
    .required()
    .items(this.orderItemsSchema),
};

这是 componentDidMount 的样子:

componentDidMount = async () => {
    const { data } = await productService.getAllProducts();
    console.log("DBPRODUCTS B4 SET", this.state.dbProducts);
    if (data) {
      this.setState({ dbdata: data });
      console.log("dbdata after set", this.state.dbdata);
    }
  };

设置后的数组(dbdata):

dbdata after set (21)
0: {createdAt: "2020-10-02T08:15:31.644Z", _id: "5f7713c5d1cee74e44af03a4", description: "Mazdar Swiffer mops", price: 8.49, inStorage: 73, …}
1: {createdAt: "2020-10-02T08:15:31.644Z", _id: "5f77142fd1cee74e44af03a5", description: "Taggba Clorox bleach", price: 3.49, inStorage: 534, …}
2: {createdAt: "2020-10-02T08:15:31.644Z", _id: "5f7715a8d1cee74e44af03a8", description: "Castle Supply Carpet cleaner", price: 9.99, inStorage: 168, …}
3: {createdAt: "2020-10-02T08:15:31.644Z", _id: "5f771601d1cee74e44af03a9", description: "Quickie All Purpose", price: 9, inStorage: 407, …}
4: {createdAt: "2020-10-02T08:15:31.644Z", _id: "5f77162cd1cee74e44af03aa", description: "All-Purpose Cleaner Spray", price: 4, inStorage: 413, …}
5: {createdAt: "2020-10-02T08:15:31.644Z", _id: "5f77167dd1cee74e44af03ab", description: "Mrs. Meyer’s Multi-Surface Cleaner", price: 3.99, inStorage: 153, …}
...

我试过像这样使用 joi-browser 的 valid() 而不是 .min().max():

description: Joi.string()
  .valid(this.state.dbdata.map((item) => item.description))
  .label("Description"),

但我没有得到预期的错误,而是得到了:"Description" must be one of [ ]; 这基本上意味着数组是空的,这意味着它还没有在 componentDidMount 中设置 对吗?

我该如何解决这个问题?

解决了在 componentDidMount 从数据库中获取数据后使用 componentDidUpdate 更新架构的问题。

orderItemsSchema = {};

schema = {};

//Fetch data from db and setState
componentDidMount = async() => {
  const {
    data: dbdata
  } = await productService.getAllProducts();
  if (dbdata) {
    this.setState({
      dbdata
    });
  }
};

//Update Joi schema after data has been fetched
componentDidUpdate = () => {
  this.orderItemsSchema = {
    id: Joi.number(),
    description: Joi.string()
      .valid(this.state.dbdata.map((item) => item.description))
      //Will be valid only if matches an item.description
      .label("Description"),
    quantity: Joi.number().min(1).label("Quantity"),
  };
  this.schema = {
    custName: Joi.string().min(2).max(30).required().label("Customer Name"),
    orderItems: Joi.array()
      .label("orderItems")
      .required()
      .items(this.orderItemsSchema),
    important: Joi.boolean().required(),
    totalPrice: Joi.number().required(),
  };
};