我有一个非常奇怪的错误。有时,当我提交表单时,“ userId” cookie不会更新。我认为我已经将问题隔离到与之相关的
return user.set({
roomId: roomId,
name: name
}).then(() => alert("finished writing"))
因为不更新cookie时,永远不会调用“完成书写”警报。我认为承诺没有得到解决,并且占用了线程,因此.then永远不会运行(因此,带有cookie更新的.then永远不会运行)。但是,我不太了解诺言,也找不到可能阻碍诺言的东西。如果有人可以帮助我或指出错误,我们将不胜感激。这是代码:
function GamePage() {
const {roomId} = useParams();
const db = firebase.firestore();
let history = useHistory();
const [userIdExistsButWrongRoom, setUserIdExistsButWrongRoom] = useState(true);
const userId = cookies.get('userId');
useEffect(() => {
if(!(typeof(userId)==="undefined")){
db.collection("users").doc(userId).get().then(function(doc){
if(doc.data().roomId === roomId){
setUserIdExistsButWrongRoom(false);
}
});
}
}, [db,roomId,userId]);
if(cookies.get('roomId')===roomId){
if(typeof(userId)==="undefined"){
return (
<div>
<EnterName />
</div>
);
} else {
if(userIdExistsButWrongRoom){
return (
<div>
<EnterName />
</div>
);
} else {
return (
<div>
<Game />
</div>);
}
}
} else {
history.push("/");
return (<div />);
}
}
function EnterName() {
const {roomId} = useParams();
const [name, setName] = useState("");
function handleChange(event) {
setName(event.target.value);
}
function handleSubmit(event) {
addNewUser(roomId,name).then(function(userId) {cookies.set('userId',userId)});
}
return (<form onSubmit={handleSubmit}>
<label>
Name:
<textarea value={name} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>);
}
function Game() {
const {roomId} = useParams();
return (<div>
<h1>
{roomId}
</h1>
</div>);
}
//Add a new user with server generated unique ID, and the given room ID to the database
//Returns the doc
function addNewUser(roomId,name) {
const db = firebase.firestore();
const user = db.collection("users").doc()
const userId = user.id;
alert(userId);
return user.set({
roomId: roomId,
name: name
}).then(() => alert("finished writing"));
}
修改
在Oliver's answer之后,我尝试实现一个asynchoronus SubmitHandler。但是,这导致甚至没有调用addNewUser函数。我发现了这个问题javascript async await Submitting a form with onsubmit using Promise,这表明异步的SubmitHandler的问题是它总是返回一个Promise,因此它在Promise解决之前提交。我尝试实施他们的建议的修复程序(如下),但现在又回到了原始问题,但是现在一直如此!
function EnterName() {
const {roomId} = useParams();
const [name, setName] = useState("");
function handleChange(event) {
setName(event.target.value);
}
async function handleSubmit(event) {
let userId = await addNewUser(roomId, name);
alert("test");
cookies.set('userId',userId);
}
function submit(event){
handleSubmit(event);
return false;
}
return (<form onSubmit={submit}>
<label>
Name:
<textarea value={name} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>);
}
function Game() {
const {roomId} = useParams();
return (<div>
<h1>
{roomId}
</h1>
</div>);
}
//Add a new user with server generated unique ID, and the given room ID to the database
//Returns the doc
async function addNewUser(roomId,name) {
const db = firebase.firestore();
const user = db.collection("users").doc()
const userId = user.id;
alert(userId);
return user.set({
roomId: roomId,
name: name
}).then(() => {
alert("finished writing");
return userId;
});
}
答案 0 :(得分:1)
Promise是异步的,因此您的处理可能在解决之前结束。使用await/async
使其等待。
尝试一下:
function EnterName() {
const {roomId} = useParams();
const [name, setName] = useState("");
function handleChange(event) {
setName(event.target.value);
}
async function handleSubmit(event) {
let userId = await addNewUser(roomId, name);
cookies.set('userId',userId);
}
return (<form onSubmit={handleSubmit}>
<label>
Name:
<textarea value={name} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>);
}
function Game() {
const {roomId} = useParams();
return (<div>
<h1>
{roomId}
</h1>
</div>);
}
//Add a new user with server generated unique ID, and the given room ID to the database
//Returns the doc
async function addNewUser(roomId,name) {
const db = firebase.firestore();
const user = db.collection("users").doc()
const userId = user.id;
alert(userId);
return user.set({
roomId: roomId,
name: name
}).then(() => {
alert("finished writing");
return userId;
});
}
答案 1 :(得分:1)
我终于解决了。问题来自于不覆盖React中onSubmit的默认行为。因此,在答应完成之前重新加载了页面,从而切断了线程。当我添加event.preventDefault();
时,此问题已解决。
这是现在可以使用的固定代码:
function EnterName(props) {
const {roomId} = useParams();
const [name, setName] = useState("");
function handleChange(event) {
setName(event.target.value);
}
function handleSubmit(event) {
addNewUser(roomId,name).then(function(user) {
cookies.set('userId',user.id);
alert("finished cookies");
props.userExists(false);
});
event.preventDefault();
return false;
}
return (<form onSubmit={handleSubmit}>
<label>
Name:
<textarea value={name} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>);
}
function Game() {
const {roomId} = useParams();
return (<div>
<h1>
{roomId}
</h1>
</div>);
}
//Add a new user with server generated unique ID, and the given room ID to the database
//Returns the doc
function addNewUser(roomId,name) {
const db = firebase.firestore();
return db.collection("users").add({
roomId: roomId,
name: name
});
}