我的通用 TextArea 组件中的错误处理不起作用

Error handling in my generic TextArea component not working

提问人:thegreenedition 提问时间:9/25/2023 更新时间:9/25/2023 访问量:12

问:

我有一个通用的文本区域组件,用于多个页面。

import { FormEvent, useEffect, useRef, useState } from 'react';
import { InfoIcon } from '~common/icons';
import { InputProps } from '~/common/components/Input/InputProps';
import { getErrorMessage } from '~/common/helpers/getInputErrorMessage';

const TextArea = ({
  autoComplete,
  classNames,
  errorMessage = {},
  id,
  infoText,
  label,
  name,
  placeholder,
  required,
  showError = false,
  variant = 'primary',
}: InputProps) => {
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  const [touched, setTouched] = useState(false);
  const [currentErrorMessage, setCurrentErrorMessage] = useState('');
  const labelId = `label-${id}`;
  const textAreaId = `textArea-${id}`;

  useEffect(() => {
    const validity = textAreaRef.current?.validity;
    if (validity) {
      setCurrentErrorMessage(getErrorMessage(validity, errorMessage));
    }
  }, [textAreaRef, errorMessage]);

  return (
    <div className={`block relative text-sm ${classNames ?? ''}`}>
      <label id={labelId} htmlFor={textAreaId}>
        {label}
      </label>
      <textarea
        ref={textAreaRef}
        name={name}
        required={required}
        cols={50}
        className={`xyz-input-${variant} mt-2 invalid-border-color-red resize-none ${
          touched || showError ? 'xyz-touched' : ''
        }`}
        id={textAreaId}
        onBlur={() => {
          setTouched(true);
        }}
        onInvalid={(ev: FormEvent<HTMLTextAreaElement>) => {
          const { validity } = ev.currentTarget;
          ev.preventDefault();
          setCurrentErrorMessage(getErrorMessage(validity, errorMessage));
        }}
        onChange={(ev: FormEvent<HTMLTextAreaElement>) => {
          const { validity } = ev.currentTarget;
          setCurrentErrorMessage(getErrorMessage(validity, errorMessage));
        }}
        autoComplete={autoComplete}
        placeholder={placeholder}
      />

      <div className="xyz-error hidden text-xyz-color-red mt-2 text-sm">{currentErrorMessage}</div>

      {infoText && (
        <div className="pt-[0.125rem]">
          <div className="text-sm mt-2 flex items-center h-5">
            <InfoIcon className="text-xyz-color-orange h-6 w-6 mr-2" /> {infoText}
          </div>
        </div>
      )}
    </div>
  );
};

export default TextArea;

它被导入到另一个组件中,如下所示:

      const Form = () => {
  const [submitFormData, { error, loading }] = useMutation(SUBMIT_FORM_DATA);
  const [revealErrors, setRevealErrors] = useState(false);
  const [formSubmitted, setFormSubmitted] = useState<boolean>();

 const handleSubmit = async (ev: FormEvent<HTMLFormElement>) => {
    const formData = new FormData(ev.currentTarget);

    submitFormData({
      variables: {
        message: formData.get('message'),
      },
    }).then(() => setFormSubmitted(true));
  };

return (
      <div>
          <form
            onSubmit={(ev) => {
              ev.preventDefault();
              handleSubmit(ev);
            }}
            onInvalid={() => setRevealErrors(true)}
          >
            <fieldset className="max-w-xl w-full">
              <TextArea
                classNames="mt-4"
                errorMessage={{
                  valueMissing: 'Write something',
                }}
                id="form-message"
                label="Your message"
                name="message"
                placeholder="A longer message"
                required
                showError={revealErrors}
                type="text"
              />
            </fieldset>
            <div className="w-full max-w-xl">
                <Button type="submit" loading={loading} disabled={loading} className="my-4 w-full">
                  Submit
                </Button>
              {error && <div className="text-xyz-color-red mt-2">Something went wrong.</div>}
            </div>
          </form>
    </div>
)
}       

这是道具:

import { ValidityStateKeys } from '~/types';

type HTMLCharInput = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';

export interface InputProps {
  autoComplete?: string;
  classNames?: string;
  errorMessage?: {
    [key in ValidityStateKeys]?: string;
  };
  id: string;
  infoText?: string;
  label: string;
  name: string;
  pattern?: string;
  placeholder?: string;
  required?: boolean;
  showError?: boolean;
  type?: HTMLCharInput;
  variant?: 'primary' | 'secondary';
}

这就是 validityKeys:

export enum ValidityStateKeys {
  BAD_INPUT = 'badInput',
  CUSTOM_ERROR = 'customError',
  PATTERN_MISMATCH = 'patternMismatch',
  RANGE_OVERFLOW = 'rangeOverflow',
  RANGE_UNDERFLOW = 'rangeUnderflow',
  STEP_MISMATCH = 'stepMismatch',
  TOO_LONG = 'tooLong',
  TOO_SHORT = 'tooShort',
  TYPE_MISMATCH = 'typeMismatch',
  VALUE_MISSING = 'valueMissing',
}

错误处理有什么问题,我该如何解决这个问题?该字段不能留空。我遗漏了一些东西,textarea 标签的所有道具真的有效吗?

HTML ReactJS 打字稿 验证 下一页 .js

评论


答: 暂无答案