#javascript #reactjs #asynchronous #axios #event-handling
Вопрос:
После вызова handleButton
, нажав Log In
кнопку один раз, значение logInStatus
пусто. Однако после второго щелчка значение logInStatus
изменится. Я знаю, что setState-это асинхронный вызов, поэтому он не обновит значение logInStatus
мгновенно. Как я должен подойти к решению?
import React, {setState, useState, useEffect } from "react";
import Axios from "axios";
const Login = () => {
useEffect(() => {
document.title = 'Log In';
});
const [data, setData] = useState(null);
const [username, setName] = useState('');
const [password, setPassword] = useState('');
const [logInStatus, setlogInStatus] = useState('');
const user = [password,username]
function read(user){
let returned = checkRegister(user);
returned.then(function(result) {
setlogInStatus(result.data.message);
//return setlogInStatus(result)
});
}
const handleButton = (e) => {
read(user);
e.preventDefault();
//logInStatus is empty here even it should contain soimething
if(logInStatus == "Successfully Authenticated"){
//do stuff
}
}
function checkRegister(user) {
const user_object = {
username: user[1],
password: user[0]
}
console.log(user_object)
var ok;
return Axios({
method: "POST",
data: user_object,
withCredentials: true,
url: "http://localhost:9000/users/login",
});
}
return(
<div className="login">
<div>
</div>
<div className="userform">
<h2 className="pagename">Log in</h2>
<form>
{/* <label>Username:</label> */}
<input
type="text"
required
value={ username }
onChange={ (e) => setName(e.target.value) }
placeholder="Username"
/>
{/* <label>Password:</label> */}
<input
type="password"
required
value={ password }
onChange={ (e) => setPassword(e.target.value) }
placeholder="Password"
/>
<button onClick={handleButton}>Log In</button>
<h1>{logInStatus} </h1>
</form>
</div>
</div>
);
}
export default Login;
Комментарии:
1. Провели ли вы тест, чтобы
setlogInStatus(result)
непосредственно получить результат обещания axios? Потому что, с моей точки зрения, вы уже потребляете обещание с первымthen
входомcheckRegister
, поэтому у вас есть два решения, первое-это то, что я говорю выше, второе-вернуть обещание неиспользованным, удаливthen
входcheckRegister
.2. Можете ли вы указать строку, которая выдает ошибку?
3. @BenoitChassignol Вторым вариантом вы имеете в виду то, что я сделал выше(отредактировано)? Я удалил
then
checkRegister
вход, но мне все равно нужно дважды нажать кнопку, чтобы получить измененные результатыlogInStatus
4. @Yousaf , как сказано в ответе
read
, является обычной функцией, поэтому я не могу ее использоватьthen
, поэтому я не должен был определять другую функцию. Но я все равно не смог решить эту проблему5. @dogsht1338 да, именно это я и имею в виду. Теперь вы не должны видеть предыдущую ошибку, верно?
Ответ №1:
Отредактируйте, я не буду удалять первый абзац ниже, но это неправильно, используйте его в качестве контекста для комментария @Yousaf ниже.
Итак, чтобы продолжить, вы попытались then
призвать обещание, которое уже было выполнено первым then
, в которое вы вложили checkRegister
. Что не может работать в связи с тем, как обрабатывать обещание, вы можете прочитать больше об этом здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise. Как я уже сказал, вам нужно выбирать между тем, потреблять его непосредственно в checkRegister
свою функцию или потреблять после read
нее. И установите состояние в соответствии с тем выбором, который вы делали раньше, где у вас есть доступ к вашему результату.
Вы должны поставить ключевое function
слово перед checkRegister
тем, как объявить его как оно.
Вы можете удалить var ok;
то, что бесполезно и используется здесь. Вы также можете удалить вызванный импорт setState
, который тоже не использовался.
И, наконец, вы можете удалить e.preventDefault();
то, что в вашем случае бесполезно, потому что вы используете простую кнопку, не связанную с вашей формой. Вы можете узнать больше о формах здесь: https://reactjs.org/docs/forms.html
Комментарии:
1. «вы попытались вызвать тогда обещание, которое уже было выполнено первым тогда» —
then()
метод также возвращает обещание, и возвращаемое им обещание разрешается значением, возвращаемым его функцией обратного вызова.2. @Yousaf, вы правы, проблема этого кода заключалась в
function
ключевых словах, вот почему мы получаемCannot read property 'then' of undefined
. Только потомуcheckRegister
, что не использовалfunction
ключевое слово. Я отредактирую свой комментарий. Тнх.
Ответ №2:
В функции чтения убедитесь, что checkuser возвращает обещание.Вы можете использовать тогда и ловить только в случае обещаний js.Из вашего кода ясно, что checkuser-это не обещание, это просто функция, поэтому просто измените ее на обещание или иным образом удалите метод then. Проверьте это, чтобы узнать о обещаниях js