在我的Reaction应用程序中,我在一个页面上有两个地址表格,它们具有两个保存地址的功能,可以将地址保存在数据库中.还有一个提交按钮,用于提交两个字段并导航到下一页(The plus button in the circle adds the address to the saved addresses list):

enter image description here

我想要做的是验证表单域,我已经通过调用useForm()钩子的两个实例来实现了:

// useForm hook
  const {
    control: senderControl,
    handleSubmit: handleSenderSubmit,
    setValue: senderSetValue,
  } = useForm({
    defaultValues: {
      senderName: '',
      senderLastName: '',
      senderPostalCode: '',
      senderPhone: '',
      senderAddress: '',
    },
  });

  // useForm hook
  const {
    control: receiverControl,
    handleSubmit: handleReceiverSubmit,
    setValue: receiverSetValue,
  } = useForm({
    defaultValues: {
      receiverName: '',
      receiverLastName: '',
      receiverPhone: '',
      receiverPostalCode: '',
      receiverAddress: '',
    },
  });

然后,我将这两个钩子的handleSubmit方法分别添加到每个字段的加号按钮的onClick(100 in RN)中.

这确实会逐个验证表单,但当我try 使用SUBMIT按钮提交整个页面时,问题就出现了.

我仍然希望在按下常规的SUBMIT按钮时能够同时验证这两个地址字段,但我不知道如何用一个handleSubmit验证这两个实例,并获得这两个字段的值的return data.

EDIT (CustomInput.js):

const CustomInput = ({
  control,
  name,
  rules = {},
  placeholder,
  secureTextEntry,
  keyboardType,
  maxLength,
  textContentType,
  customStyle,
}) => (
  <Controller
    control={control}
    name={name}
    rules={rules}
    render={({field: {onChange, onBlur, value}, fieldState: {error}}) => (
      <View style={customStyle || styles.container}>
        <TextInput
          value={value}
          onBlur={onBlur}
          onChangeText={onChange}
          placeholder={placeholder}
          keyboardType={keyboardType}
          maxLength={maxLength}
          textContentType={textContentType}
          secureTextEntry={secureTextEntry}
          style={[
            styles.textInput,
            {
              borderColor: !error
                ? GENERAL_COLORS.inputBorder
                : GENERAL_COLORS.error,
            },
          ]}
        />
        {error && <Text style={styles.errMsg}>{error.message || 'error'}</Text>}
      </View>
    )}
  />
);

Usage:

<CustomInput
    control={control}
    name="senderPostalCode"
    rules={{
      required: 'Postal Code is Required',
    }}
    placeholder="Postal Code"
    keyboardType="number-pad"
    textContentType="postalCode"
    customStyle={{
      width: '49%',
      marginBottom: hp(1),
    }}
/>

有没有可能做到这一点呢?

推荐答案

Thanks to @TalgatSaribayev 's comment for leading me to this solution.

I didn't need to set any specific validation rules for the address field and in the end I separated the sender and receiver forms into two different pages.

首先,我必须指出,我使用useWatchhook来获取最新的值,而不是使用getValuesAPI获取postalCodeaddress字段的输入值.

// Watch inputs
const watchedInputs = useWatch({
  control,
  name: ['senderPostalCode', 'senderAddress'],
});

当我将输入值getValues保存到一个变量中时,我得到的是以前的状态,而不是最近的状态,解决这个问题的唯一方法是无论何时只要我想要获得最近的状态,就调用getValues('INPUT_NAME').(In the end I resolved to use 102).

///////////////////////////////////////////////////////////////////////////////////////////////////

正如@TalgatSaribayev指出的那样,只创建一个useForm个实例就足够了.我所要做的就是创建一个函数,该函数将手动设置错误,并在按下保存地址按钮后判断它们的有效性.

// Check if sender postal code input has error
const senderHasError = () => {
  if (!/^\d+$/.test(watchedInputs[0])) {
    setError('senderPostalCode', {
      type: 'pattern',
      message: 'Postal Code must be a number',
    });
    return true;
  }
    
  // Any other rules
  if (YOUR_OWN_RULE) {
    setError('senderPostalCode', {
      type: 'custom',
      message: 'CUSTOM_MESSAGE',
    });
    return true;
  }
    
  // Clear error and return false
  clearErrors('senderPostalCode');
  return false;
};

问题是,即使通过了验证,错误也不会得到更新(清除).好像无效输入不会附加onChange个事件侦听器来重新验证它.当您以onSubmit模式useForm提交表单时,默认情况下会发生一些事情.(https://react-hook-form.com/api/useform)

因此,我决定使用useFormtrigger API手动触发表单验证,并在按下保存地址按钮时监听postalCode字段的更改.

首先,我创建了一个切换状态,用于更改触发状态:

// Postal code onSubmit event state
const [triggered, setTriggered] = useState(false);

然后在useMemo中使用useFormtriggerAPI,仅当triggered状态设置为TRUE并且输入字段的值已更改时才触发输入验证:

// Manually trigger input validation if postal code's onSubmit event is true
useMemo(() => {
  if (triggered) trigger('senderPostalCode');
}, [watchedInputs[0]]);

我假设我使用triggerAPI触发输入字段的方式与useForm的模式onSubmit的工作方式相同:在用户按下保存地址按钮时启动触发器,方法是将trigger的状态更改为setTrigger.

// Add address to sender favorites
const handleAddSenderFavAddress = () => {
  // Trigger on the press event
  setTriggered(true);

  // Return if sender postal code input has error
  if (senderHasError()) return;

  // SAVE ADDRESS LOGIC
  ///////////////////////////////
};

除了useFormhandleSubmitfunction的一般验证之外,这是我设法验证单独的输入域的唯一方法.

我欢迎更多可能导致更好解决方案的答案.

Javascript相关问答推荐

脚本.js:3:20未捕获的类型错误:无法读取空的属性(读取addEventHandler)

布局样式在刷新时不持续

如何提取Cypress中文本

使用redux-toolet DelivercThunks刷新访问令牌

ReactJS中的material UI自动完成类别

在贝塞尔曲线的直线上找不到交叉点:(使用@Pomax的bezier.js)

Google图表时间轴—更改hAxis文本 colored颜色

. NET中Unix时间转换为日期时间的奇怪行为

从WooCommerce Checkout Country字段重新排序国家,保持国家同步

用JS从平面文件构建树形 struct 的JSON

Eval vs函数()返回语义

让chart.js饼图中的一个切片变厚?

钛中的onClick事件需要在两次点击之间等待几秒钟

无法读取未定义的属性(正在读取合并)-react RTK

基于产品ID更新条带产品图像的JavaScript命中错误

P5JS-绘制不重叠的圆

有没有办法通过使用不同数组中的值进行排序

在ChartJS中使用spanGaps时,是否获取空值的坐标?

如何检测当前是否没有按下键盘上的键?

AstroJS混合模式服务器终结点返回404