首页 > 解决方案 > 带有 material-ui 的 React-hook-form 不会保持 onBlur() 方法中的值变化

问题描述

我是 react-hook-form 世界的新手。我正在尽我最大的努力去理解,但我仍然缺少一些东西。我需要欧比旺的帮助!

这是问题所在:

我有一个输入数字,它使用<Textfield>react-hook-form 组件内的 Material-ui 组件呈现<Controller/。在这个输入上,我需要验证输入的数字应该在 16 到 99 之间。使用 Material-UI,您可以传递参数inputProps={{min:16, max:99}}来阻止本机输入上的数字!伟大的!

但是如果用户手动输入一个值呢?然后我希望能够在 onBlur 验证方法中阻止它,这就是我所做的:

<TextField
      onBlur={(e) =>{
        const currentValue = Number(e.target.value);
        if (!(currentValue >= minAge && currentValue <= maxAge)) {
            e.target.value = String(minAge);
            ref.current.value = String(minAge);
        }
        onBlur();
        console.log('TextField onBlur(): ', e.target.value);
      }}
      inputRef={ref}

      inputProps={{
        min:minAge,
        max:maxAge
      }}
/>

但是,当我在模糊后记录该值时,它告诉我没有任何变化。请帮忙。

这是完整的文件:

import React, {useEffect} from "react";
import { TextField } from "@material-ui/core";
import { Controller, useFormContext } from "react-hook-form";
import { ErrorMessage } from "@hookform/error-message";
import { ErrorMessageContainer } from "./ErrorMessageContainer";
import { FieldWrapper } from "./FieldWrapper";

interface AgeTextboxProps {
  name: string;
  label?: string;
}

export const AgeTextbox = ({ name, label }: AgeTextboxProps) => {
  const { errors, control } = useFormContext();
  const minAge = 16;
  const maxAge = 99

  return (
    <FieldWrapper caption={label}>
      <Controller
        name={name}
        control={control}
        rules={{
          required: { value: true, message: `You must enter the ${label} age` },
          min: { value: minAge, message: `The ${label} age cannot be lower than 16` },
          max: { value: maxAge, message: `The ${label} age cannot be higher than 99` }
        }}
        render={({ onChange, onBlur, value, ref }) => (
          <TextField
            onChange={(e) => onChange(e.target.value)}
            onBlur={(e) =>{
              const currentValue = Number(e.target.value);
              if (!(currentValue >= minAge && currentValue <= maxAge)) {
                  e.target.value = String(minAge);
                  ref.current.value = String(minAge);
              }
              onBlur();
              console.log('TextField onBlur(): ', e.target.value);
            }}
            onFocus={(event) => {
                event.target.select();
            }}
            inputRef={ref}
            value={value || 0}
            error={errors[name] ? true: false}

            role={"textbox"}
            variant="outlined"
            type={"number"}

            inputProps={{
              min:minAge,
              max:maxAge
            }}
          />
        )}
      />

      <ErrorMessage
        errors={errors}
        name={name}
        as={<ErrorMessageContainer />}
      />
    </FieldWrapper>
  );
};

export default AgeTextbox;

这里还有一个代码框链接: https ://codesandbox.io/s/eloquent-ishizaka-980qb?file=/src/AgeTextBox.tsx

标签: javascriptreactjsmaterial-uionblurreact-hook-form

解决方案


这是我为你做的。可能是你想要这种行为。

我只是在 onBlur 里面调用了 onChange

onBlur={(e) => {
              const currentValue = Number(e.target.value);
              if (currentValue < minAge || currentValue > maxAge) {
                onChange(String(minAge));
              } else {
                onChange(e.target.value);
              }
              onBlur();
              console.log("TextField onBlur(): ", e.target.value);
            }}

https://codesandbox.io/s/modest-archimedes-6c1nl?file=/src/AgeTextBox.tsx


推荐阅读