在 react-native 中,变量被渲染但值没有被传递到子屏幕

问题描述 投票:0回答:1

React/React-Native 新手 验证后主页打开,它有两个选项卡“付款”和“通知”。我想访问付款选项卡中的用户电子邮件和位置。电子邮件已成功呈现在主页的第一个文本部分。但是该值未在付款选项卡中传递。 location 对象也有类似的问题。我知道我遗漏了一些关于渲染序列的基本知识,但我不知道要搜索什么。

import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import { useAuthentication } from '../utils/hooks/useAuthentication';
import { signOut, getAuth } from 'firebase/auth';
import * as Location from 'expo-location';

const auth = getAuth();

const Tab = createMaterialTopTabNavigator();

function NoticeTab({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Notice Tab</Text>
    </View>
  );
}

function PaymentTab({ navigation, route }) {
  const { email, location } = route.params;
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>{email}</Text>
      <Text> {location ? location.coords.latitude.toString() : "Waiting for coordinates"}</Text>
      <Text> {location?.coords.longitude.toString()}</Text>
    </View>
  );
}

export default function Home({ navigation }) {
  const { user } = useAuthentication();
  const [email, setEmail] = useState(user?.email);

  const [location, setLocation] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);

  useEffect(() => {
    setEmail(user?.email);
    (async () => {
      console.log("useEffect");

      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }

      let location = await Location.getCurrentPositionAsync({});
      setLocation(location);

    })();
  }, [user?.email, location]);

  return(
      <View style={{ flex: 10 }}>
        <Text>Welcome {user?.email}</Text>
        <Tab.Navigator>
          <Tab.Screen name="Notice" component={NoticeTab} />
          <Tab.Screen name="Payment" component={PaymentTab} initialParams={{ email: email, location: location }} navigation={navigation}} />
        </Tab.Navigator>
      </View>
);
}

useAuthentication
钩看起来像下面

import React from 'react';
import { getAuth, onAuthStateChanged, User } from 'firebase/auth';

const auth = getAuth();

export function useAuthentication() {
  const [user, setUser] = React.useState();

  React.useEffect(() => {
    const unsubscribeFromAuthStatuChanged = onAuthStateChanged(auth, (user) => {
      if (user) {
        // User is signed in, see docs for a list of available properties
        // https://firebase.google.com/docs/reference/js/firebase.User
        setUser(user);
      } else {
        // User is signed out
        setUser(undefined);
      }
    });

    return unsubscribeFromAuthStatuChanged;
  }, []);

  return {
    user
  };
}
reactjs react-native react-hooks react-navigation
1个回答
0
投票

我正在使用 React-Native,但无论如何我都会尝试解释一些东西。

通常当我使用某种“导航器”时,比如 TabNavigator,我从不在导航器本身中放置任何应用程序逻辑。如果你真的需要一个静态的“顶栏”,在所有屏幕上都显示“你好,[email protected]!”没关系,但我认为问题是那些“初始参数”。

如果你想让一个组件知道一些东西,并且这个“东西”可以在不传递它的情况下被检索到,那就去做吧。只需让

PaymentTab
对象重新声明所有:

function PaymentTab({ navigation, route }) {
  const { user } = useAuthentication();
  const [email, setEmail] = useState(user?.email);
  ...
}

请记住,当您将一些不可序列化的值作为参数传递时,React 会生气(但无论如何都会允许您)。

我可以把我用作 React Native 参考的这个链接留给你(你也应该找到一些关于“React”的东西): https://reactnavigation.org/docs/tab-based-navigation/

您的应用程序的问题可能是首先呈现该应用程序还不知道邮件,因为用户可能未定义。在你的 TabNavigator 中,你传递的初始参数是未定义的,它没有得到更新,因为它只是一个已经设置为未定义的初始参数,即使屏幕重新渲染。

© www.soinside.com 2019 - 2024. All rights reserved.