【问题标题】:Yup mapping schema to element like choices[] (react and formik)是的,将架构映射到诸如选择[](react 和 formik)之类的元素
【发布时间】:2019-09-09 14:07:42
【问题描述】:

我有一个表单,其中包含一组复选框,名称为:choices[]。我有一个 PHP 后端,复选框的名称无法更改。我正在尝试构建 Yup 模式以创建一个验证规则,其中必须选择其中一个选项。

我目前的解决方案是让一个 onchange 更新一个隐藏字段的值。这个值是被验证的。但这不可能。

有什么想法吗?我试过了,但这不起作用。我似乎无法在网上找到一个很好的例子,所以我决定在这里问。

choices[]: Yup.boolean().required('error we need to pick one')

编辑添加一些代码:

import React, { ChangeEvent, useState, useEffect } from 'react'

import Checkbox from ...
import CheckboxProps from ...
import CheckboxGroup from ...
import Label from ...

export interface CheckboxGroupChoicesProps {
  setFieldValue?: any
}

/**
 *
 * @param props
 */
const CheckboxGroupChoices: React.FunctionComponent<
  CheckboxGroupChoicesProps
> = props => {
  /**
   * State management for the checked counter, we use this in a hidden field for validation purposes
   */
  const [checkedCounter, setCheckedCounter] = useState(0)
  const [initialLoad, setInitialLoad] = useState(1)
  const hiddenFieldName = 'cbxSFVal'

  /**
   * Enable validation on this checkbox field
   *
   * This is a required field, as such we need to ensure that at least one of the
   * checkboxes has been selected. By incrementing the <hidden> field we ensure
   * that we have an idea on how many of the checkboxes have been selected. We
   * then use this within the validation.tsx to do some stuff.
   *
   * @param e: ChangeEvent
   */
  function validateCheckboxRequired(e: ChangeEvent) {
    if ((e.currentTarget as HTMLInputElement).checked) {
      setCheckedCounter(checkedCounter + 1)
    } else {
      setCheckedCounter(checkedCounter - 1)
    }
  }

  /**
   * Handle the state change for checkedCounter.
   * setFieldValue is from formik and we can use it to update the hidden field
   * that we use for validation.
   */
  useEffect(() => {
    if (initialLoad != 1) {
      props.setFieldValue(hiddenFieldName, checkedCounter)
    } else {
      setInitialLoad(0)
    }
  }, [checkedCounter])

  /**
   * Create an array of checkboxes that will be sent to the Checkboxgroup molecule.
   *
   * @return Array<ChecboxProps>
   */
  const getCheckboxes: any = () => {
    const checkboxes: Array<React.ReactElement<CheckboxProps>> = []
    const options = ['Car', 'Van', 'Bike']

    options.forEach((option, key) => {
      checkboxes.push(
        <Checkbox
          label={option}
          value={option}
          disabled={false}
          name={'choices[]'}
          key={`choices-${key}`}
          handleOnClick={(e: ChangeEvent) => validateCheckboxRequired(e)}
        />
      )
    })

    return checkboxes
  }

  return (
    <>
      <Label>Pick choices</Label>
      <CheckboxGroup columns={3}>{getCheckboxes()}</CheckboxGroup>
      <input type={'hidden'} name={hiddenFieldName} />
    </>
  )
}

export default CheckboxGroupChoices

我的组件本质上呈现以下 html:

<div>
<checkbox name='choices[]' value='car'> Car<br />
<checkbox name='choices[]' value='van'> Car<br />
<checkbox name='choices[]' value='bike'> Car<br />
</div>

我使用 formik 进行验证,使用如下验证模式:

<Formik
    enableReinitialize
    initialValues={postingForm.initialValues}
    validationSchema={postingForm.validationSchema}
>
{form => (
  <Form> ....</Form>
)}
</Formik>

在提交时,我想确认我的至少一项选择已被选中。我当前的组件将根据复选框的选中状态 +1 和 -1 隐藏字段的值。这是使用验证的:

cbxSFVal: Yup.number().min(1, required_message),

但我确信必须有一种更简单的方法来验证复选框。

【问题讨论】:

    标签: reactjs formik yup


    【解决方案1】:

    您需要使用引号设置属性名称。

    const schema = Yup.object().shape({
      "choices[]": Yup.boolean().required('error we need to pick one')
    });
    

    另外,请确保您以正确的方式访问该属性。

    // Syntax Error
    obj.choices[]
    
    // Correct Way
    obj["choices[]"]
    

    编辑:

    您可以做的是拥有一个包含每个复选框状态的数组,因此如果您有 3 个选项,它将是一个长度为 3 且带有 false 的数组,并且您在单击时将值更新为 true。

    这样,您可以验证其中一个复选框是否为真

    "choices[]": Yup.array().oneOf(['true']).required('error we need to pick one')
    

    【讨论】:

    • "choices[]" 应该是"choices": Yup.array.of(boolean)... 否?
    • @Rikin 他的问题是I have a form that has an collection of checkboxes where the name is: choices[]. I have a PHP backend and the name of the checkboxes cant change,我的理解是表单属性的名称必须是choices[]。如果这不是他的意思,他应该更新问题以使其更清楚。
    • 是的,元素的名称是choices[] 我已经尝试了Rikin 所说的并且有误报。 @Vencovsky 我似乎无法确定我是否以正确的方式访问这些选项。我正在使用 formik,它正在做黑盒魔术,所以不确定。
    • @Andy 请分享完整代码。仅使用一行代码很难理解您的组件是如何工作的。
    • 好的,我会编辑我的问题。你想要什么?显然我不能全部给你,但我可以给你我的组件?
    猜你喜欢
    • 2020-08-05
    • 2011-04-13
    • 2017-04-19
    • 2021-02-02
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2011-05-25
    • 2020-06-09
    相关资源
    最近更新 更多