Reactjs 如何使函数等待用户数据在useContext提供程序中更新?
我希望新用户在首次登录时输入他们的详细信息。这包括输入用户名、姓名、个人资料图片等 当他们提交了他们的详细信息后,我等待firebase的确认,然后我想将他们转发到他们的个人资料(链接结构是domain/p/:username) 但是,每次我尝试它时,它都会尝试指向domain/p/undefined 当我使用react-dev工具进行检查时,我可以看到用户名已成功发送到我的状态提供程序,因此我认为这只是时间问题,这就是问题所在 欢迎页面功能如下:Reactjs 如何使函数等待用户数据在useContext提供程序中更新?,reactjs,firebase,asynchronous,react-hooks,firebase-storage,Reactjs,Firebase,Asynchronous,React Hooks,Firebase Storage,我希望新用户在首次登录时输入他们的详细信息。这包括输入用户名、姓名、个人资料图片等 当他们提交了他们的详细信息后,我等待firebase的确认,然后我想将他们转发到他们的个人资料(链接结构是domain/p/:username) 但是,每次我尝试它时,它都会尝试指向domain/p/undefined 当我使用react-dev工具进行检查时,我可以看到用户名已成功发送到我的状态提供程序,因此我认为这只是时间问题,这就是问题所在 欢迎页面功能如下: //The first method begi
//The first method begins the update and checks if the username already exists.
const update = async (e) => {
if (
firstName.trim() === "" ||
lastName.trim() === "" ||
username.trim() === "" ||
bio.trim() === "" ||
addressOne.trim() === "" ||
city.trim() === "" ||
county.trim() === "" ||
postCode.trim() === "" ||
photos.length === 0
) {
window.alert("Invalid data!\nOnly Address line 2 can be empty");
} else {
var usernameRef = db
.collection("users")
.where("username", "==", username);
usernameRef.get().then((docs) => {
if (docs.size === 1) {
docs.forEach((doc) => {
if (doc.id === currentUser.uid) {
sendUpdate();
} else {
window.alert("Username taken");
}
});
} else {
sendUpdate();
}
});
}
};
//This method puts the initial data into firebase except the profile picture
function sendUpdate() {
setLoading("loading");
db.collection("users")
.doc(currentUser.uid)
.set(
{
username: username,
name: firstName,
surname: lastName,
bio: bio,
address1: addressOne,
address2: addressTwo,
notifications: [],
city: city,
county: county,
postcode: postCode,
newUser: false,
},
{ merge: true }
)
.then(() => {
updatePhoto();
})
.catch((err) => console.log(err));
}
//This method uploads the profile picture, then gets the downloadURL of the photo just uploaded and puts it into the user document created in method 2.
//It also trys to send the user to their profile afterwards, but it always ends up as undefined.
const updatePhoto = async () => {
const promises = [];
var userREF = db.collection("users").doc(currentUser.uid);
photos.forEach((photo) => {
const uploadTask = firebase
.storage()
.ref()
.child(
`users/` + currentUser.uid + `/profilePicture/profilePicture.jpg`
)
.put(photo);
promises.push(uploadTask);
uploadTask.on(
firebase.storage.TaskEvent.STATE_CHANGED,
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (snapshot.state === firebase.storage.TaskState.RUNNING) {
console.log(`Progress: ${progress}%`);
}
},
(error) => console.log(error.code),
async () => {
const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
userREF
.update({
profilePicture: downloadURL,
})
.then(async () => {
updateUserData().then(() => {
setLoading("complete");
setTimeout(() => {
history.push("/p/" + userData.username);
}, 3000);
});
});
}
);
return "completed";
});
};
这是我的AuthContext提供程序:(UpdateUserData()函数是将数据放入firebase后更新数据的函数)
import React,{useContext,useState,useffect}来自“React”;
从“./firebase”导入{auth,db};
const AuthContext=React.createContext();
导出函数useAuth(){
返回useContext(AuthContext);
}
导出函数AuthProvider({children}){
const[currentUser,setCurrentUser]=useState();
const[userData,setUserData]=useState();
const[loading,setLoading]=useState(true);
功能注册(电子邮件、密码){
返回auth.createUserWithEmailAndPassword(电子邮件,密码);
}
功能登录(电子邮件、密码){
返回带有email和password(电子邮件,密码)的身份验证登录;
}
异步函数updateUserData(){
如果(当前用户){
var userData=db.collection(“users”).doc(currentUser.uid);
等待用户数据
.get()
。然后((doc)=>{
如果(文件存在){
setUserData(doc.data());
返回“成功”;
}
})
.catch((错误)=>{
log(“获取文档时出错:”,错误);
返回“错误”;
});
}
}
函数注销(){
setUserData();
返回auth.signOut();
}
功能重置密码(电子邮件){
返回auth.sendPasswordResetEmail(电子邮件);
}
功能更新邮件(电子邮件){
返回currentUser.updateEmail(电子邮件);
}
函数updatePassword(密码){
返回currentUser.updatePassword(密码);
}
useffect(()=>{
const unsubscribe=auth.onAuthStateChanged((用户)=>{
setCurrentUser(用户);
设置加载(假);
如果(用户){
var userData=db.collection(“users”).doc(auth.currentUser.uid);
用户数据
.get()
。然后((doc)=>{
如果(文件存在){
setUserData(doc.data());
}
})
.catch((错误)=>{
log(“获取文档时出错:”,错误);
});
}
});
退订;
}, []);
常量值={
当前用户,
用户数据,
更新SERDATA,
登录,
报名,
注销,
重置密码,
更新邮件,
更新密码,
};
返回(
TIA!您可以通过将重定向链接移出您的updatePhoto
并使其生效(或基于代码流的任何其他选项)来解决此问题然后只需设置一个状态或检查所需的数据,如userdata.userName
已经存在,如果其未定义,则阻止重定向,您可以显示加载程序组件,例如,否则执行重定向
基本示例:
useEffect(() => {
if(userData.username){
history.push("/p/" + userData.username);
}
}, [userData.username])
const myUpdateFunction = useCallBack(() => {
fetch().then(v => {
setUserData(v);
})
}, [])
是的,这很有效,谢谢!欢迎你:D
useEffect(() => {
if(userData.username){
history.push("/p/" + userData.username);
}
}, [userData.username])
const myUpdateFunction = useCallBack(() => {
fetch().then(v => {
setUserData(v);
})
}, [])