#reactjs #use-state #handle #use-ref #getstate
Вопрос:
Я добавил в свой код два обработчика. Сначала вводится почта и запускается handleStart, затем от пользователя получают имя пользователя и пароль, а затем при нажатии кнопки активируется handleFinish и выполняются назначения информации. Состояние setEmail работает, но состояния пароля и имени не работают
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const history = useHistory();
const url = "http://localhost:3002/register";
const emailRef = useRef();
const passwordRef = useRef();
const usernameRef = useRef();
const handleStart = () => {
setEmail(emailRef.current.value);
}
const handleFinish = async (e) => {
e.preventDefault();
console.log("ref data", passwordRef.current.value,usernameRef.current.value)
//it works and shows values
setPassword(passwordRef.current.value);
setName(usernameRef.current.value);
console.log("state data", email, password, name)
//status values are empty except for email
try {
await axios.post(url, { email, name, password });
history.push("/");
} catch (err) { }
}
и мои коды возврата (HTML) :
{!email ? (
<div className="input">
<input type="email" placeholder="email address" ref={emailRef} />
<button className="registerButton" onClick={handleStart}>
Get Started
</button>
</div>
) : (
<form className="input">
<input type="username" placeholder="username" ref={usernameRef} />
<input type="password" placeholder="password" ref={passwordRef} />
<button className="registerButton" onClick={handleFinish}>
Start
</button>
</form>
)}
Ответ №1:
Лучше использовать useState
для хранения и получения значений и элемента управления, а не использовать ref
.
Вот код с использованием состояния, который может вам помочь:
const App = () => {
const history = useHistory();
const url = "http://localhost:3002/register";
const [step, setStep] = useState(0)
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [username, setUsername] = useState("")
const handleStart = () => {
setStep(1)
}
const handleFinish = async (e) => {
e.preventDefault();
console.log("data: ", email, password, username)
try {
await axios.post(url, { email, name, password });
history.push("/");
} catch (err) { }
}
return (
step === 0 ? (
<div className="input">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="email address"
/>
<button className="registerButton" onClick={handleStart}>
Get Started
</button>
</div>
) : (
<form className="input">
<input
type="username"
placeholder="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<input
type="password"
placeholder="password"
value={password}
onChange={() => setPassword(e.target.value)}
/>
<button className="registerButton" onClick={handleFinish}>
Start
</button>
</form>
)
)
}
Комментарии:
1. Теперь все работает, спасибо
Ответ №2:
Это очень хорошо известная проблема, объясняемая здесь тысячи раз, то,
что изменения состояния являются внутренне асинхронными , означает, что мы не получим обновленное состояние в следующей строке немедленно, требуется время для завершения выполнения setPassword
и setName
, поэтому следующая строка после заданного состояния, консоль.журнал будет иметь старые значения
console.log(passwordRef.current.value)
console.log(usernameRef.current.value)
это должно иметь значения и войти в консоль, но нет password
, и name
это приведенное ниже поведение является правильным, известным и здесь нет проблем,
console.log("state data", email, password, name)
//status values are empty except for email
лучше было бы, если бы этот приведенный ниже хак всегда работал на меня,
await axios.post(url, { email, usernameRef.current.value, passwordRef.current.value });
Ответ №3:
Если вы хотите выполнить какое-либо действие, основанное на изменении значения электронной почты, пароля, имени, то использование useEffect может быть лучшим вариантом. Вы можете вызвать API или выполнить любое действие в результате изменения этих значений. Пожалуйста, найдите следующий код —
useEffect(() => {
await axios.post(url, { email, name, password });
history.push("/");
return () => {
// handle cancelling or other clean up
}
}, [email, password, name]);