Javascript 在保存更改时,而不是在启动时,响应本机组件更新。[火基,使用效果]

Javascript 在保存更改时,而不是在启动时,响应本机组件更新。[火基,使用效果],javascript,firebase,react-native,google-cloud-firestore,react-hooks,Javascript,Firebase,React Native,Google Cloud Firestore,React Hooks,我还是一个新手程序员,希望我的代码可以理解 我有一个Firestore DB,访问存储的数据没有问题,问题在于React组件或Expo 这个问题发生在我的软件的各个部分,我只想包括一个(如果你们帮我解决它,我想我可以解决其他问题) 这是我的身份验证流程: LoginForm.js(使用电子邮件创建用户并传递给Firebase)->AddExtranfo(保存一些配置文件数据)->ProfileInfoWorker(保存一些额外数据)->帐户(如果用户已登录,则转到UserGuest otherw

我还是一个新手程序员,希望我的代码可以理解

我有一个Firestore DB,访问存储的数据没有问题,问题在于React组件或Expo

这个问题发生在我的软件的各个部分,我只想包括一个(如果你们帮我解决它,我想我可以解决其他问题)

这是我的身份验证流程:

LoginForm.js(使用电子邮件创建用户并传递给Firebase)->AddExtranfo(保存一些配置文件数据)->ProfileInfoWorker(保存一些额外数据)->帐户(如果用户已登录,则转到UserGuest otherwhise to UserLogged)->UserLogged(获取信息)->InfoUser(显示信息的组件)

//UserLogged.js
导出默认功能UserLogged(道具){
const[userInfo,setUserInfo]=useState(null);
const[perfilData,setPerfilData]=useState(“”);
firebase.auth().onAuthStateChanged((用户)=>{
setUserInfo(用户);
});
useffect(()=>{
如果(用户信息){
设置加载(真);
设ref=db.collection(“perfil final”);
让query=ref
.where(“userId”,“==”,firebase.auth().currentUser.uid)
.get()
。然后((快照)=>{
if(snapshot.empty){
log(“没有匹配的文档”);
返回;
}
snapshot.forEach((doc)=>{
setPerfilData(doc.data());
});
设置加载(假);
})
.catch((错误)=>{
log(“获取文档时出错”,err);
});
}
}, []); 
返回(
{userInfo&&(
)}
我在这里打印信息

//InfoUser.js
export default function InfoUser(props) {
  const {
    userInfo: { uid, displayName, email },
    perfilData,
  }
   return (
    <View>
      <View>
        <Text>
          {displayName ? displayName : "Anonymous"}
        </Text>
        <Text>{email ? email : "Anonymous"}</Text>
      </View>

    </View>
  );
}
//InfoUser.js
导出默认函数InfoUser(道具){
常数{
用户信息:{uid,displayName,email},
性能数据,
}
返回(
{displayName?displayName:“匿名”}
{电子邮件?电子邮件:“匿名”}
);
}
问题是,当我进入UserLogged屏幕时,它会加载“匿名”,但如果我在代码编辑器上按CTRL+S,并获得刷新警报,我就会得到正确的数据。发生了什么? 我假设我的代码一开始是空的,所以它不显示数据,但是当它改变时,为什么不更新呢

提前谢谢,干杯

编辑:

//RegisterForm.js
导出默认函数注册表执行(道具){
const[formData,setFormData]=useState(defaultFormValue());
const onChange=(e,type)=>{
setFormData({…formData,[type]:e.nativeEvent.text});
const[loading,setLoading]=useState(false);
const navigation=useNavigation();
//…这里我验证空字段,然后。。
设置加载(真);
火基
.auth()
.createUserWithEmailAndPassword(formData.email,formData.password)
.然后(()=>{
设置加载(假);
导航。导航(“外部信息”);
})
.catch(()=>{
设置加载(假);
console.log(“电子邮件已在使用”);
});
};
返回(
onChange(e,“电子邮件”)}
/>
onChange(e,“密码”)}
密码={true}
secureTextEntry={showPassword?false:true}
/>
onChange(e,“重复密码”)}
密码={true}
secureTextEntry={showRepeatPassword?false:true}
/>
);
}
函数defaultFormValue(){
返回{
电邮:“,
密码:“”,
重复密码:“”,
};
}
在这里,当用户按下account选项卡时,我重定向,如果用户已登录,则转到UserLogged,如果未登录,则转到UserLogged屏幕

//Account.js
export default function Account() {
  const [login, setLogin] = useState(null);
  firebase.auth().onAuthStateChanged((user) => {
    !user ? setLogin(false) : setLogin(true);
  });

  if (login === null) return <Loading isVisible={true} text="Cargando..." />;

  return login ? <UserLogged /> : <UserGuest />;
}

//Account.js
导出默认函数帐户(){
const[login,setLogin]=useState(null);
firebase.auth().onAuthStateChanged((用户)=>{
!user?setLogin(false):setLogin(true);
});
if(login==null)返回;
返回登录?:;
}
这里我使用React导航,尝试首先获取用户类型,以便在用户是工作者时显示一些选项卡,在用户是客户端时显示其他选项卡

//Navigation.js
export default function Navigation(props) {
  const [userType, setUserType] = useState("");
  const [userInfo, setUserInfo] = useState("")
  const [nombreRuta, setNombreRuta] = useState("Solicitudes");
  const [login, setLogin] = useState(null);

  firebase.auth().onAuthStateChanged((user) => {
    !user ? setLogin(false) : setLogin(true);
    if (!user) {
    userType("");
    }else{
    setUserInfo(user);
    }
  });

  useEffect(() => {
    let isSubscribed = true;
    if (login) {
      let perfilRef = db.collection("perfiles");
      perfilRef
        .where("userId", "==", firebase.auth().currentUser.uid)
        .get()
        .then((snapshot) => {
          if (snapshot.empty) {
            console.log("No matching documents.");
            return;
          }
          snapshot.forEach((doc) => {
            if (isSubscribed) {
              setTipoUsuario(doc.data().userType);
            }
          });
        })
        .catch((err) => {
          console.log("Error getting documents", err);
        });
    }
    return () => (isSubscribed = false);
  }, [userInfo]); //Tried with: login and userType

  return (
    <NavigationContainer>
      <Tab.Navigator
        initialRouteName="requests"
        tabBarOptions={{
          inactiveTintColor: "#646464",
          activeTintColor: "#F7931C",
        }}
        screenOptions={({ route }) => ({ 
          tabBarIcon: ({ color }) => screenOptions(route, color),
        })}
      >
        {userType == "worker" && (
          <Tab.Screen
            name="solicitudesworker"
            component={RequestsWorkerStack}
            options={{ title: "Requests" }}
          ></Tab.Screen>
        )}
        {userType == "client" && (
          <Tab.Screen
            name="restaurants"
            component={RequestsStack}
            options={{ title: "Requests" }}
          ></Tab.Screen>
        )}

        <Tab.Screen
          name="topworkers"
          component={topworkers}
          options={{ title: "Top Workers" }}
        ></Tab.Screen>
        <Tab.Screen
          name="search"
          component={SearchStack}
          options={{ title: "Search" }}
        ></Tab.Screen>

        <Tab.Screen
          name="account"
          component={AccountStack}
          options={{ title: "Account" }}
        ></Tab.Screen>
      </Tab.Navigator>
    </NavigationContainer>
  );
}


//Navigation.js
导出默认功能导航(道具){
const[userType,setUserType]=useState(“”);
const[userInfo,setUserInfo]=useState(“”)
const[nombreRuta,setNombreRuta]=使用状态(“请求”);
const[login,setLogin]=useState(null);
firebase.auth().onAuthStateChanged((用户)=>{
!user?setLogin(false):setLogin(true);
如果(!用户){
用户类型(“”);
}否则{
setUserInfo(用户);
}
});
useffect(()=>{
让isSubscribed=true;
如果(登录){
设perfilRef=db.collection(“perfiles”);
perfilRef
.where(“userId”,“==”,firebase.auth().currentUser.uid)
.get()
。然后((快照)=>{
if(snapshot.empty){
log(“没有匹配的文档”);
返回;
}
snapshot.forEach((doc)=>{
如果(已订阅){
setTipoUsuario(doc.data().userType);
}
});
})
.catch((错误)=>{
log(“获取文档时出错”,err);
});
}
return()=>(isSubscribed=false);
},[userInfo]);//尝试使用:login和userType
返回(
({ 
tabBarIcon:({color})=>屏幕选项(路线、颜色),
})}
>
{userType==“工作者”&&(
)}
{userType==“客户端”&&(
)}
);
}

发生的情况是,组件挂载时正在调用useEffect,然后再也没有调用过

useEffect(() => {
if (userInfo) {
  setLoading(true);
  let ref = db.collection("perfil-final");
  let query = ref
    .where("userId", "==", firebase.auth().currentUser.uid)
    .get()
    .then((snapshot) => {
      if (snapshot.empty) {
        console.log("No matching documents.");
        return;
      }
      snapshot.forEach((doc) => {
        setPerfilData(doc.data());
      });
      setLoading(false);
    })
    .catch((err) => {
      console.log("Error getting documents", err);
    });
}
}, [userInfo]);
这是因为使用不带依赖性数组的useEffect只调用函数一次。它在userInfo状态有机会更新之前被调用,因此,它的所有方式都为空。(当您热重新加载时,它会强制调用useEffect。这在生产环境中不会发生)

您需要将userInfo传递到d
//Navigation.js
export default function Navigation(props) {
  const [userType, setUserType] = useState("");
  const [userInfo, setUserInfo] = useState("")
  const [nombreRuta, setNombreRuta] = useState("Solicitudes");
  const [login, setLogin] = useState(null);

  firebase.auth().onAuthStateChanged((user) => {
    !user ? setLogin(false) : setLogin(true);
    if (!user) {
    userType("");
    }else{
    setUserInfo(user);
    }
  });

  useEffect(() => {
    let isSubscribed = true;
    if (login) {
      let perfilRef = db.collection("perfiles");
      perfilRef
        .where("userId", "==", firebase.auth().currentUser.uid)
        .get()
        .then((snapshot) => {
          if (snapshot.empty) {
            console.log("No matching documents.");
            return;
          }
          snapshot.forEach((doc) => {
            if (isSubscribed) {
              setTipoUsuario(doc.data().userType);
            }
          });
        })
        .catch((err) => {
          console.log("Error getting documents", err);
        });
    }
    return () => (isSubscribed = false);
  }, [userInfo]); //Tried with: login and userType

  return (
    <NavigationContainer>
      <Tab.Navigator
        initialRouteName="requests"
        tabBarOptions={{
          inactiveTintColor: "#646464",
          activeTintColor: "#F7931C",
        }}
        screenOptions={({ route }) => ({ 
          tabBarIcon: ({ color }) => screenOptions(route, color),
        })}
      >
        {userType == "worker" && (
          <Tab.Screen
            name="solicitudesworker"
            component={RequestsWorkerStack}
            options={{ title: "Requests" }}
          ></Tab.Screen>
        )}
        {userType == "client" && (
          <Tab.Screen
            name="restaurants"
            component={RequestsStack}
            options={{ title: "Requests" }}
          ></Tab.Screen>
        )}

        <Tab.Screen
          name="topworkers"
          component={topworkers}
          options={{ title: "Top Workers" }}
        ></Tab.Screen>
        <Tab.Screen
          name="search"
          component={SearchStack}
          options={{ title: "Search" }}
        ></Tab.Screen>

        <Tab.Screen
          name="account"
          component={AccountStack}
          options={{ title: "Account" }}
        ></Tab.Screen>
      </Tab.Navigator>
    </NavigationContainer>
  );
}


useEffect(() => {
if (userInfo) {
  setLoading(true);
  let ref = db.collection("perfil-final");
  let query = ref
    .where("userId", "==", firebase.auth().currentUser.uid)
    .get()
    .then((snapshot) => {
      if (snapshot.empty) {
        console.log("No matching documents.");
        return;
      }
      snapshot.forEach((doc) => {
        setPerfilData(doc.data());
      });
      setLoading(false);
    })
    .catch((err) => {
      console.log("Error getting documents", err);
    });
}
}, [userInfo]);