Я проверил другие вопросы, они мне не помогли
Я построил ловушку React для проверки входных данных моей формы. Однако это вызывает бесконечную повторную визуализацию l oop. Я отследил проблему до массива зависимостей useEffect
. Когда я исключаю зависимость validators
, она прекрасно работает! Я не буду когда-либо менять validators
во время выполнения, так что эта пропа не нужна в массиве зависимостей? Мой ESLint
react-hooks-plugin
продолжает предупреждать меня, что зависимость validators
отсутствует. Пожалуйста, помогите мне. Можно ли исключить зависимость validators
из массива зависимостей useEffect
, если я не буду изменять ее во время выполнения? Вот мой хук и мой компонент формы:
import { useState, useEffect } from "react";
function setObjectValues<
K extends { [key: string]: unknown },
T
>(
object: K,
value: T
): { [key in keyof K]?: T } {
const initialResults: {
[key in keyof K]?: T;
} = {};
for (const key in object) {
initialResults[key] = value;
}
return initialResults;
}
export function useValidation<
K,
T extends {
[key: string]: (value: K) => boolean;
}
>(
value: K,
validators: T
): {
valid: boolean;
results: { [key in keyof T]?: boolean };
} {
const [results, setResults] = useState<
{ [key in keyof T]?: boolean }
>(setObjectValues(validators, true));
useEffect(() => {
const newResults: {
[key in keyof T]?: boolean;
} = {};
for (const key in validators) {
const valid = validators[key](value);
newResults[key] = valid;
}
setResults(newResults);
}, [value, validators]);
const valid = Object.values(results).every(
(item) => item === true
);
return { valid, results };
}
Мой компонент:
import { NextPage } from "next";
import {
useFirebase,
useValidation,
} from "app/hooks";
import {
useState,
useCallback,
FormEvent,
} from "react";
import { useRouter } from "next/router";
type InputType = "email" | "password";
const SignUp: NextPage = () => {
const firebase = useFirebase();
const router = useRouter();
const [email, setEmail] = useState("");
const {
valid: emailValid,
results: emailValidationResults,
} = useValidation(email, {
containsAt: (value) => value.includes("@"),
});
const [password, setPassword] = useState("");
const {
valid: passwordValid,
results: passwordValidationResults,
} = useValidation(password, {
isLongEnough: (value) => value.length >= 8,
containsLowerCase: (value) =>
value.toUpperCase() !== value,
containsUpperCase: (value) =>
value.toLowerCase() !== value,
containsNumber: (value) => /\d/.test(value),
});
const handleSubmit = useCallback(
(event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (
emailValid === true &&
passwordValid === true &&
email !== "" &&
password !== ""
) {
const error = firebase.createUser(
email,
password
);
if (error) {
console.warn(error.code);
} else {
router.push("/");
}
} else {
console.warn("Invalid user values");
}
},
[
email,
emailValid,
firebase,
password,
passwordValid,
router,
]
);
console.log(emailValid, passwordValid);
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input
value={email}
onChange={(event): void =>
setEmail(event.target.value)
}
id="email"
placeholder="Email"
/>
<p>{emailValid}</p>
<label htmlFor="password">Password</label>
<input
value={password}
onChange={(event): void =>
setPassword(event.target.value)
}
id="password"
placeholder="Password"
/>
<p>{passwordValid}</p>
<button type="submit">Submit</button>
</form>
);
};
export default SignUp;