React Custom hooks - 继承?

React Custom hooks - inheritance?

我知道 React Hooks 的全部意义在于摆脱基于 class 的组件并提升功能组件。但是react hooks中是否可以实现继承呢?

例如这里,我创建了两个钩子。 1. useEmailFormatValidator 验证输入 (onChange) 是否为有效的电子邮件格式。 2. useEmailSignupValidator 继承了 useEmailFormatValidator 但扩展了它的功能来验证用户可以在 (onBlur) 事件发生时使用用户名。

这些的重点是 useEmailFormatValidator 可用于登录表单,而 useEmailSignupValidator 可用于注册表单。

下面是我的代码

使用电子邮件格式验证器

import { useState } from 'react';

export const useEmailFormatValidator = () => {
  const [value, setValue] = useState('');
  const [validity, setValidity] = useState(false);

  const regex = /^(([^<>()[\]\.,;:\s@"]+(\.[^<>()[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

  const inputChangeHandler = event => {
    setValue(event.target.value.trim());
    if (regex.test(String(event.target.value.trim()).toLowerCase())) {
      setValidity(true);
    } else {
      setValidity(false);
    }
  };

  return { value: value, onChange: inputChangeHandler, validity };
};

使用电子邮件注册验证器

import { useState } from 'react';
import { useEmailFormatValidator } from "../auth";

export const useEmailSignupValidator = () => {
  const [value, setValue] = useState('');
  const [validity, setValidity] = useState(false);
  const emailFormatValidator = useEmailFormatValidator();

  const inputChangeHandler = event => {
    emailFormatValidator.onChange(event);
    setValue(emailFormatValidator.value);
    setValidity(emailFormatValidator.validity);
  };

  const verifyUserNameExists = event => {
    // Verify username is availble in back-end.
  };

  return { value: value, onChange: inputChangeHandler, onBlur: verifyUserNameExists, validity };
};

当我 运行 测试时,下面的内容没有按预期工作并且 'value' 和 'validity' 未定义。

 const inputChangeHandler = event => {
    emailFormatValidator.onChange(event);
    setValue(emailFormatValidator.value);
    setValidity(emailFormatValidator.validity);
  };

自定义挂钩中是否有继承?或者你如何重用代码,这就是 react hooks 的目的?

恕我直言,这并不是真正的自定义挂钩。为什么不做这样的事情?

const isValidEmail = email => {
    const regex = /^(([^<>()[\]\.,;:\s@"]+(\.[^<>()[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return regex.test(email);
};

const MyComponent = () => {
    const [inputVal, setInputVal] = useState('');

    return(
        <div>
            <input 
                type='text'
                name='my-input'
                onChange={e => {
                    const email = e.target.value;
                    if(isValidEmail(email)){
                        setInputVal(email);
                    }else{
                        alert('invalid email')
                    }
                }}
            />
        </div>
    )
}