Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何使函数等待用户数据在useContext提供程序中更新?_Reactjs_Firebase_Asynchronous_React Hooks_Firebase Storage - Fatal编程技术网

Reactjs 如何使函数等待用户数据在useContext提供程序中更新?

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

我希望新用户在首次登录时输入他们的详细信息。这包括输入用户名、姓名、个人资料图片等

当他们提交了他们的详细信息后,我等待firebase的确认,然后我想将他们转发到他们的个人资料(链接结构是domain/p/:username)

但是,每次我尝试它时,它都会尝试指向domain/p/undefined

当我使用react-dev工具进行检查时,我可以看到用户名已成功发送到我的状态提供程序,因此我认为这只是时间问题,这就是问题所在

欢迎页面功能如下:

//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);
  })
}, [])