触摸的属性没有被重置

IT技术 javascript reactjs typescript react-native formik
2021-04-28 13:27:18

我有一个 Formik 表单,我可以在其中获取用户输入并在提交后运行查询。

当我单击搜索按钮时,会呈现一个列表。所有列表项都有自己的按钮。当我第一次单击绿色添加按钮(从列表项中)时,该按钮不起作用。不打印控制台日志的内容。相反,将触发 inputField 的 onBlur 事件。但是,如果我再次单击 + 按钮,则它可以工作并打印 no。此问题在模拟器/手机中可见,而不是在沙箱上的 Web 模式中可见。

export const AddFriendScreen: React.FunctionComponent = () => {
  const initialValues: FormValues = {
    input: '',
  };

  const [showFlatList, setShowFlatList] = useState<UsersLazyQueryHookResult>(
    '',
  );


  const handleSubmitForm = (
    values: FormValues,
    helpers: FormikHelpers<FormValues>,
  ) => {

    loadUsers({
      variables: {
        where: {
          OR: [
            { phoneNumber: newPhoneNumber },],
        },
      },
    });
    helpers.resetForm();
 };

  return (
    <SafeAreaView style={styles.safeAreaViewContainer}>
      <View style={styles.searchTopContainer}>
        <View style={styles.formContainer}>
          <Formik
            initialValues={initialValues}
            onSubmit={handleSubmitForm}
            validationSchema={validationSchema}>
            {({ handleChange, handleBlur, handleSubmit, values }) => (
              <View style={styles.searchFieldContainer}>
                <View style={styles.form}>
                  <FieldInput
                    handleChange={handleChange}
                    handleBlur={handleBlur}
                    value={values.input}
                    fieldType="input"
                    icon="user"
                    placeholderText="E-Mail oder Telefonnummer oder Name"
                  />
                  <ErrorMessage
                    name="input"
                    render={(msg) => <ErrorText errorMessage={msg} />}
                  />
                </View>
                <View style={styles.buttonContainer}>
                  <ActionButton buttonText="Suchen" onPress={handleSubmit} />
                </View>
              </View>
            )}
          </Formik>
        </View>
        <View style={styles.listHolder}>
          {data && showFlatList !== null && (
            <UsersFoundList
              data={data}/>
          )}
        </View>
      </View>
    </SafeAreaView>
  );
};

小吃展:

https://snack.expo.io/@nhammad/jealous-beef-jerky

[![在此处输入图像描述][1]][1]

编辑:

找到了一种解决方法,但仍然对更简单的解决方案持开放态度。仍然没有弄清楚究竟是什么导致了这个问题。

1个回答

但是,这会导致在提交表单并返回/呈现数据后立即显示 formik 错误。例如,错误表明输入字段不应为空。
...
为什么键盘会干扰这个?

可能是因为当你打电话时,你Keyboard.dismiss()实际上没有聚焦输入,这将触发validateOnBlur事件。
因此,当您取消关注某个字段(模糊)时,它会尝试验证 ( validateOnBlur),并且由于该字段为空,它将显示验证。

只有当我们尝试在没有输入的情况下重新提交表单时,才会出现错误。

如果错误只在您提交表单时显示,您应该传递给Formik组件validateOnBlur={false}有了这个,当你调用时它不会显示错误消息Keyboard.dismiss(),因为它会删除模糊验证。

但它仍然会在输入更改时进行验证,从而触发validateOnChange. 您还可以传递给Formik组件validateOnChange={false}以禁用更改验证,它只会在您提交表单时验证(按下按钮)。

请注意,validateOnChange并且validateOnBlurtrue在默认情况下。

编辑:

您需要添加validateOnBlur={false}但不是调用Keyboard.dismiss()您需要调用fieldRef.current.blur(). 但是要使其工作,您需要React.forwardRef在输入组件中使用。

所以你需要创建 fieldRef

const fieldRef = useRef();

传递给组件

<FieldInput
    ref={fieldRef} // passing the ref
    handleChange={handleChange}
    handleBlur={handleBlur}
    value={values.input}
    fieldType="input"
    icon="user"
    placeholderText="input"
/>

并且您需要将FieldInputwith包裹起来React.forwardRef并将其传递refInput组件。

// wrapping the component with React.forwardRef
export const FieldInput: React.FunctionComponent<FieldInputProps> = React.forwardRef(({
  handleChange,
  handleBlur,
  fieldType,
  placeholderText,
  value,
  style,
  rounded,
  //ref,
}, ref) => {
  return (
    <Item rounded={rounded} style={[styles.inputItem, style]}>
      <Input
        ref={ref} // passing the ref 
        autoFocus={true}
        autoCapitalize="none"
        style={styles.inputField}
        placeholder={placeholderText}
        keyboardType="default"
        onChangeText={handleChange(fieldType)}
        onBlur={handleChange(fieldType)}
        value={value}
      />
    </Item>
  );
});

现在在handleSubmitForm你打电话fieldRef.current.blur()

const handleSubmitForm = (
    values: FormValues,
    helpers: FormikHelpers<FormValues>,
) => {
    // other logic from your submit
    if (fieldRef && fieldRef.current)
          fieldRef.current.blur();
};

有了这个,您将解决您的问题和评论中的问题。

工作示例

关于的说明 useRef

我们需要使用useRef钩子,这样我们才能获得Input组件的元素,以便能够调用该blur函数,因此不要专注于输入,可以单击加号按钮。我们需要使用useRef钩子,因为这就是您ref在功能组件中创建的方式