首页 > 解决方案 > 无法使用 Firebase Firestore 有条件地渲染 React Native 屏幕,理由是“缺少返回”

问题描述

我正在使用 React Native 开发一个小组项目,我们有一个名为 的页面EventListScreen.js,它由选项卡导航器调用。在此文件中,我们显示从 Firebase Cloud Firestore 数据库调用的事件列表。我们希望根据用户是“志愿者”还是“组织”,有条件地使用“添加事件”按钮显示此页面。

这是该文件的完整代码,以免遗漏任何内容。

const EventListScreen = (props) => {
  const [events, setEvents] = useState([]);

  useEffect(() => {
    firebase
      .firestore()
      .collection("events")
      .onSnapshot((querySnapshot) => {
        const events = [];
        querySnapshot.docs.forEach((doc) => {
          const { address, eName } = doc.data();
          events.push({
            id: doc.id,
            address,
            eName,
          });
        });
        setEvents(events);
      });
  }, []);

  const OrganizationScreen = () => {
    <ScrollView>
      <Button
        onPress={() => props.navigation.navigate("AddEvent")}
        title="Add Event"
      />
      {events.map((event) => {
        return (
          <ListItem
            key={event.id}
            bottomDivider
            onPress={() => {
              props.navigation.navigate("EventDetails", {
                userId: event.id,
              });
            }}
          >
            <ListItem.Chevron />
            <ListItem.Content>
              <ListItem.Title>{event.uId}</ListItem.Title>
              <ListItem.Title>{event.address}</ListItem.Title>
              <ListItem.Title>{event.eName}</ListItem.Title>
            </ListItem.Content>
          </ListItem>
        );
      })}
    </ScrollView>;
  };

  const VolunteerScreen = () => {
    {/* ... the same thing as the above without the <Button> element ... */}
  };

  firebase
    .firestore()
    .collection("users")
    .doc(firebase.auth().currentUser.uid)
    .get()
    .then((doc) => {
      if (doc.data().accountType == "Volunteer") {
        return VolunteerScreen();
      } else {
        return OrganizationScreen();
      }
    });
};

export default EventListScreen;

根据从 Firebase 检测到的用户类型,是否可以显示两种类型的 HTML?非常基本:当用户类型为“志愿者”时,我们只想删除或停用该按钮。上面显示的这个方法,以及其他一些语法派生,将导致 React 认为没有返回渲染的错误。

编辑

这是我在 Firebase 部分中放置日志语句以进行逻辑时的样子。它可以正确地识别出用户是“志愿者”类型,但它给出的错误解释是“渲染没有返回任何内容。这通常意味着缺少返回语句。或者,不渲染任何内容,返回 null。” 这可以通过在 Firebase 位之后放置一个简单的 return 语句来解决,但这似乎覆盖了我们想要呈现的其他 HTML。

所以......也许这里有某种范围问题?

文档数据

标签: firebasereact-nativegoogle-cloud-firestore

解决方案


您实施的方式使事情变得复杂。

在 useEffect 中有如下流程,首先加载用户类型,然后加载事件,根据 userType 呈现按钮,直到加载用户显示 ActivityIndi​​cator,代码应如下所示。

const EventListScreen = (props) => {
  const [events, setEvents] = useState([]);
  const [userType,setUserType]=useState();

  useEffect(() => {
  firebase
    .firestore()
    .collection("users")
    .doc(firebase.auth().currentUser.uid)
    .get()
    .then((doc) => {
       setUserType(doc.data().accountType);
      firebase
      .firestore()
      .collection("events")
      .onSnapshot((querySnapshot) => {
        const events = [];
        querySnapshot.docs.forEach((doc) => {
          const { address, eName } = doc.data();
          events.push({
            id: doc.id,
            address,
            eName,
          });
        });
        setEvents(events);
      });
    });
  }, []);

  if(!userType)
   return <ActivityIndicator/>;

  return (
    <ScrollView>
      {
        //if this is true button would be shown
        userType!=='Volunteer' && <Button
        onPress={() => props.navigation.navigate("AddEvent")}
        title="Add Event"
      />
      }
      {events.map((event) => {
        return (
          <ListItem
            key={event.id}
            bottomDivider
            onPress={() => {
              props.navigation.navigate("EventDetails", {
                userId: event.id,
              });
            }}
          >
            <ListItem.Chevron />
            <ListItem.Content>
              <ListItem.Title>{event.uId}</ListItem.Title>
              <ListItem.Title>{event.address}</ListItem.Title>
              <ListItem.Title>{event.eName}</ListItem.Title>
            </ListItem.Content>
          </ListItem>
        );
      })}
    </ScrollView>
  );
};

推荐阅读