如何让我的服务器端 Joi 验证与 redux-form 一起正常工作?

Posted

技术标签:

【中文标题】如何让我的服务器端 Joi 验证与 redux-form 一起正常工作?【英文标题】:How do I get my server-side Joi validation to work properly with redux-form? 【发布时间】:2019-08-14 23:57:54 【问题描述】:

我在后端 Express 服务器上进行了 Joi 验证。我能够将验证消息从后端获取到 redux 错误状态对象,但是如何正确设置这个 redux 对象状态以正确显示前端的 redux-form 消息。尤其是当错误从“需要名称”到“名称必须至少为 2 个字符”之类的内容来回切换时

我尝试通过导入 SubmissionError 并在发生验证错误时抛出一个新的 SubmissionError 对象来执行 redux-form 文档所说的操作。

看起来 this 位于传递给 redux-forms 自己的 this.props.handleSubmit 方法的回调函数中。

但是在我当前的代码中,我得到一个“react-dom.development.js:57 Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys )。如果你打算渲染一个孩子的集合,请改用数组。”现在出错了,

Input 组件所在的组件。

class WorkoutNew extends React.Component 
  onSubmit = formValues => 

    this.props.createWorkout(formValues, this.props.history);
  ;

  render() 
    return (
      <div>
        <h1 className="title is-3">Create a workout</h1>
        <SingleForm onSubmit=this.onSubmit form="newWorkout" />
      </div>
    );
  


const mapStateToProps = ( errors ) => 
  return  errors ;
;

export default connect(
  mapStateToProps,
   createWorkout 
)(withRouter(WorkoutNew));

重用单输入表单组件。我将 form="value" 作为 props 传入,以设置此表单的每次使用都具有唯一的表单值。

class SingleForm extends React.Component 
  onSubmit = formValues => 
    console.log("Form Values", formValues);
    console.log("PROPS", this.props);

    if (formValues) 
      throw new SubmissionError(
        name: this.props.errors
      );
    

    this.props.onSubmit(formValues);
  ;

  render() 
    return (
      <div>
        <form onSubmit=this.props.handleSubmit(this.onSubmit)>
          <Field label="Name" name="name" type="text" component=InputField />
          <button
            type="submit"
            className="button is-primary is-large"
            style= marginTop: "20px" 
          >
            Submit
          </button>
        </form>
      </div>
    );
  


const mapStateToProps = ( errors ) => 
  return  errors ;
;

export default reduxForm()(connect(mapStateToProps)(SingleForm));

这里我传入一个空对象,因为我多次使用这个组件,我将表单:'value' 作为道具传递。

我的动作创建者。

export const createWorkout = (formValues, history) => dispatch => 
  axios
    .post("/api/workouts", formValues)
    .then(res => 
      history.push("/workouts");
      // Push back to workouts page
    )
    .catch(err => dispatch( type: GET_ERRORS, payload: err.response.data ));
;

我希望发生的是,当我提交输入时,它会在输入下显示服务器端验证错误。这些错误也被正确提取到我的 redux 错误对象中。

【问题讨论】:

【参考方案1】:

在 redux 中保持短暂状态被认为是不好的做法,我建议使用 Formik 将所有表单逻辑保留在组件中,您还会发现 Formik 处理提交的方式允许使用 Formik 包为每个字段设置错误。或者,我建议您考虑使用Yup 进行同步客户端验证,API 几乎与Joi 完全相同。正如 Joi 存储库中所述,您不应使用 Joi 进行客户端验证,因为此库是在考虑 nodeJS 的情况下开发的。

【讨论】:

“在 redux 中保持短暂状态是不好的做法”是什么意思?也感谢您的建议! 这可以追溯到global variables are bad 的原则,Redux 是一种冗长且结构化的全局状态,根据 Dan Abramov(创建者)的说法,您应该只保留与整个应用程序相关的状态或需要以复杂的方式处理。简而言之,如果您可以使用本地状态,请使用本地状态,不要强行让所有东西都可以全局访问

以上是关于如何让我的服务器端 Joi 验证与 redux-form 一起正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥JOI比AJV更受欢迎?

如何在 Joi 字符串验证中使用枚举值

在 joi 和 express-validation 中允许字符串为空或空

Joi 验证 - 与 POST 中的日期进行比较

Joi 对象验证:如何验证具有未知键名的值?

Joi验证忽略嵌套键