首页 > 解决方案 > 为什么从组件中提取钩子时的工作方式不同?

问题描述

这是我的带有钩子的组件

const UserCreatePassword = () => {
  const [password, setPassword] = useState('');
  
  const [hasValidLength, setValidLength] = useState(null);
  const [hasNumber, setNumber] = useState(null);
  const [hasUpperCase, setUpperCase] = useState(null);
  const [hasLowerCase, setLowerCase] = useState(null);

  useEffect(() => {
    setValidLength(password.length >= 8 && password.length < 25);
    setUpperCase(password.toLowerCase() !== password);
    setLowerCase(password.toUpperCase() !== password);
    setNumber(/\d/.test(password));

  }, [password]);


  const handleUsersInput = (e) => {
    setPassword(e.target.value);
  };

  return (
           ...
            <TextInput name="password" onChange={(e) => handleUsersInput(e)} value={password} />
           ...
  );
};

这工作得很好,并且对用户的输入进行密码验证。然后我的下一步是从中提取一个自定义钩子。我现在有:

// hook file
export default function usePasswordValidation(password = '', minLength = 8, maxLength = 25) {
  const [hasValidLength, setValidLength] = useState(null);
  const [hasNumber, setNumber] = useState(null);
  const [hasUpperCase, setUpperCase] = useState(null);
  const [hasLowerCase, setLowerCase] = useState(null);

  useEffect(() => {
    setValidLength(password.length >= minLength && password.length < maxLength);
    setUpperCase(password.toLowerCase() !== password);
    setLowerCase(password.toUpperCase() !== password);
    setNumber(/\d/.test(password));

  }, [password, minLength, maxLength]);

  return { hasValidLength, hasNumber, hasUpperCase, hasLowerCase };
}
//component file

const UserCreatePassword = () => {
  const [password, setPassword] = useState('');

  const {
    hasValidLength,
    hasNumber,
    hasUpperCase,
    hasLowerCase,
  } = usePasswordValidation(password);


  const handleUsersInput = (e) => {
    setPassword(e.target.value);
  };

  return (
           ...
            <TextInput name="password" onChange={(e) => handleUsersInput(e)} value={password} />
           ...
  );
};

现在,当我提取钩子时,它比用户输入落后了一步。例如我输入't'它验证空字符串,然后我添加e它并验证t等等。

我知道 setState 是一个异步过程,但是

  1. 我希望提取的钩子与内部组件相同
  2. 我不能在组件usePasswordValidation内调用我的钩子useEffect,因为这会给我一个错误,并且可能违反使用钩子的模式。那我应该在这里做什么?

谢谢!

标签: reactjsreact-hooks

解决方案


推荐阅读