#reactjs
Вопрос:
Я новичок в react. Я создаю представление «вход», у меня есть два поля в форме, email
и password
. Мне нужно проверить, когда эти входные данные пусты, чтобы применить определенный icon
класс, и если они не пусты, примените другой actived
класс.
<span className={emailIsEmpty ? "icon" : "icon actived"}>
Этот класс предназначен просто для изменения цвета значков, когда пользователь вводит данные во входные данные.
Я создаю «Эффект использования» для каждого поля.
Если элемент изменится, он проверит, пусты ли входные данные, и вернет логическое значение, указывающее текущее состояние.
// Email Field
useEffect(() => {
if (email === "") {
emailIsEmpty = true;
} else {
emailIsEmpty = false;
}
}, [email]);
но я не могу выполнить эту функцию
Строка 33:25: Присвоения переменной ‘passwordIsEmpty’ внутри React Hook useEffect будут потеряны после каждого рендеринга. Чтобы сохранить значение с течением времени, сохраните его в крючке useRef и сохраните изменяемое значение в свойстве». current». В противном случае вы можете переместить эту переменную непосредственно в useEffect
Строка 24:22: Назначения переменной ’emailIsEmpty’ внутри React Hook useEffect будут потеряны после каждого рендеринга. Чтобы сохранить значение с течением времени, сохраните его в крючке useRef и сохраните изменяемое значение в свойстве». current». В противном случае вы можете переместить эту переменную непосредственно в useEffect
LoginView.js
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const LoginView = function () {
let emailIsEmpty,
passwordIsEmpty = null;
const [formState, setFormState] = useState({
email: "",
password: "",
});
const { email, password } = formState;
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
};
// Email Field
useEffect(() => {
if (email === "") {
emailIsEmpty = true;
} else {
emailIsEmpty = false;
}
}, [email]);
// Password Field
useEffect(() => {
if (password === "") {
passwordIsEmpty = true;
} else {
passwordIsEmpty = false;
}
}, [password]);
return (
<div className="container">
<div className="card-login">
<div className="card-img">
<img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
<h1>Login</h1>
</div>
<form>
<div className="form-input">
<span className={emailIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={passwordIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
</div>
</div>
);
};
export default LoginView;
Ответ №1:
Удалите эффект использования в вашем коде для изменения входного значения.Это не лучший подход, он будет повторно отображать компонент при каждом изменении значения. это может быть возможно, если вы сделаете так, чтобы вы могли просто проверить свою электронную почту formState.email или пароль formState. Теперь в вашей функции onChnageHandler.
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
//put your condition here
if (formState.email=="")
{
setEmailisEmpty(true);
}
else{
setEmailisEmpty(false);
}
};
<form>
<div className="form-input">
<span className={emailIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={passwordIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
Ответ №2:
На мой взгляд, вам не нужны два флага(emailIsEmpty и passwordIsEmpty). Скорее, вы можете использовать само состояние для условного добавления класса.
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const LoginView = function () {
const [formState, setFormState] = useState({
email: "",
password: "",
});
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
};
return (
<div className="container">
<div className="card-login">
<div className="card-img">
<img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
<h1>Login</h1>
</div>
<form>
<div className="form-input">
<span className={!formState.email? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={!formState.password ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
</div>
</div>
);
};
export default LoginView;
Ответ №3:
Вы обновляете переменную внутри useEffect
функции, которая не будет работать при рендеринге. Потому что компонент react отображает только на основе state
изменений или props
изменений.
Таким образом, вы можете проверить постоянную переменную перед возвратом, но не внутри useEffect
.
emailIsEmpty = email === "";
passwordIsEmpty = password === "";
return (
....
Таким образом, ваш компонент должен выглядеть следующим образом-
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const LoginView = function () {
let emailIsEmpty,
passwordIsEmpty = null;
const [formState, setFormState] = useState({
email: "",
password: "",
});
const { email, password } = formState;
const handleInputChange = function (e) {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
};
emailIsEmpty = email === "";
passwordIsEmpty = password === "";
return (
<div className="container">
<div className="card-login">
<div className="card-img">
<img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
<h1>Login</h1>
</div>
<form>
<div className="form-input">
<span className={emailIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-envelope-open-text"></i>
</span>
<input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
</div>
<div>
<div className="form-input">
<span className={passwordIsEmpty ? "icon" : "icon actived"}>
<i class="fas fa-key"></i>
</span>
<input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
</div>
</div>
<div>
<button className="button response">Login</button>
</div>
<div className="forget-password">
<Link to="/">Forgot password?</Link>
</div>
</form>
</div>
</div>
);
};
export default LoginView;
Для нескольких классов вы можете использовать пакет под названием classnames для объединения нескольких классов вместе.