Javascript 在保存更改时,而不是在启动时,响应本机组件更新。[火基,使用效果]
我还是一个新手程序员,希望我的代码可以理解 我有一个Firestore DB,访问存储的数据没有问题,问题在于React组件或Expo 这个问题发生在我的软件的各个部分,我只想包括一个(如果你们帮我解决它,我想我可以解决其他问题) 这是我的身份验证流程: LoginForm.js(使用电子邮件创建用户并传递给Firebase)->AddExtranfo(保存一些配置文件数据)->ProfileInfoWorker(保存一些额外数据)->帐户(如果用户已登录,则转到UserGuest otherwhise to UserLogged)->UserLogged(获取信息)->InfoUser(显示信息的组件)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
//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]);