react-native - 如何使用 expo 减少 React Navigation TopTabNavigator 中的请求数?

我是React Native 的新手,目前我正在使用expo 开发应用程序。我正在使用 react navigation 6 中的 TopTabNavigator 并且我不明白如何减少请求的数量。基本上,每当我点击某个选项卡时,都会发出请求。 (因为重新创建了组件——即使我回到上一个相同的选项卡,也没有修改数据)。我尝试使用 react navigation 中的 useFocusEffect ,但它没有按预期工作。也许我应该在 ProfileTabsScreen 中提出请求并通过 props 将数据传递到特定的选项卡?

主要部件

const ProfileStatsScreen = (props) => {
  const { userId } = props.route.params;
  const { initialRoute, username } = props.route.params;

  const RatingsDetails = () => <RatingsTab userId={userId} />;
  const FollowersDetails = () => <FollowersTab userId={userId} />;
  const FollowingsDetails = () => <FollowingsTab userId={userId} />;

  return (
    <SafeAreaView style={styles.screen}>
      <Header title={username} />
      <TopTabContainer initialRouteName={initialRoute}>
        <Tab.Screen
          name="Ratings"
          component={RatingsDetails}
          options={{ tabBarLabel: "Reviews" }}
        />
        <Tab.Screen
          name="Followers"
          component={FollowersDetails}
          options={{ tabBarLabel: "Followers" }}
        />
        <Tab.Screen
          name="Following"
          component={FollowingsDetails}
          options={{ tabBarLabel: "Followings" }}
        />
      </TopTabContainer>
    </SafeAreaView>
  );
};

选项卡组件(评级)

export const RatingsTab = ({ userId }) => {
  const { user } = useAuth();
  const [reviews, setReviews] = useState([]);
  const [loading, setLoading] = useState(false);

  useFocusEffect(
    React.useCallback(() => {
      setLoading(true);
      axios
        .get(`${process.env.BASE_ENDPOINT}/users/${userId}/reviews`, {
          headers: { Authorization: `Bearer ${user?.token}` },
        })
        .then((res) => {
          setReviews(res.data.reviews);
          setLoading(false);
        })
        .catch((err) => {
          console.log(err);
          setLoading(false);
        });
      setLoading(false);
    }, [userId, user?.token])
  );

  const renderRatings = ({ item }) => {
    const { reviewer, rating, review, createdAt } = item;

    return (
      <CardRatings
        avatar={reviewer?.avatar}
        name={reviewer?.name}
        date={moment(createdAt).format("LL")}
        rating={rating}
        review={review}
        service={"Tuns"}
      />
    );
  };

  return (
    <>
      {!loading && (
        <FlatList
          data={reviews}
          keyExtractor={(item) => item?._id}
          renderItem={renderRatings}
        />
      )}
      {loading && <Spinner />}
    </>
  );
};

回答1

您非常接近解决方案,您的 useFocusEffect 配置正确。换行

useFocusEffect(
    React.useCallback(() => {
      setLoading(true);

读书

useFocusEffect(
    React.useCallback(() => {
      if (isLoading) return; 
      setLoading(true);

即,如果加载为真,则不要进行 axios 调用。虽然这并不能消除额外请求的可能性,但它应该会大大减少您看到的内容。

此外,由于您使用的是 .then,请将回调的最后一行包装在 .finally 中。

.finally(()=> {
  setLoading(false)
});

否则,您的加载状态将在 promise 解析之前设置为 false。

回答2

谢谢,但不幸的是无法正常工作。假设我已经在 RatingsTab 中并且我有数据,因为到目前为止已经提出了请求。如果我去 FollowersTab 然后我回到 RatingsTab 如果数据没有改变我不想打电话。 if (isLoading) return; 我认为这对我没有帮助,因为加载状态一开始是错误的(当重新创建 Ratings Tab 组件时)。

相似文章

随机推荐

最新文章