【问题标题】:refetch data every time you enter the screen每次进入屏幕时重新获取数据
【发布时间】:2020-09-30 06:34:12
【问题描述】:

我有一个运行查询的屏幕,然后根据其结果,我通过UserList 组件呈现一些项目。使用 UserList 组件中的一个按钮,我运行一个突变(删除一个项目)。在这种情况下,因为组件是链接的。我通过了deleteContact函数并在其中使用了refetch()。所以当我删除一个用户时,ui会自动更新,删除的用户会被移除。

但是,我有另一个到 AddContact 的组件,它并没有真正链接到 Whitelist 组件(导航除外)。所以当我添加一个用户并回到Whitelistscreen 时,ui 没有更新。未呈现新用户。每次重新访问Whitelistscreen 时,我有什么方法可以调用 refetch() 吗?

export const Whitelist: React.FunctionComponent = (props) => {

  // useEffect(() => {
  //   refetch()
  // }, []);

  const [deleteUserRelationMutation] = useDeleteUserRelationMutation({
    onCompleted: (index: number) => {
      refetch();
      Alert.alert('Contact Deleted');
    },
    onError: _onDeleteUserRelationError
  });

  const onDeleteContact = (relationId: number) => {
    deleteUserRelationMutation({
      variables: { id: relationId}
  })
  };

  const { loading, error, data, refetch } = useUsersQuery({
    variables: {
      where: { id: 1 },
    },
  });

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <Container style={{ flex: 1, alignItems: 'center' }}>
<Item style={styles.addToWhitelist}>
          <Icon name="add" onPress={() => navigation.navigate('AddContact')} />
          <Text >Add contact</Text>
        </Item>
        <ContactList data={data} onDeleteContact={onDeleteContact}></ContactList>
      </Container>
    </SafeAreaView>
  );
};
export const ContactList: React.FunctionComponent<UserProps> = ({ data, onDeleteContact }) => {

  if (!data) return null;
  return (
    <View style={styles.users}>
    {data.users.nodes[0].userRelations.map(
      (item: { relatedUser: RelatedUser, type: RelationType, id: number}) => {
        const userName = item.relatedUser.firstName.concat(' ').concat(item.relatedUser.lastName);
        return (
          <View style={styles.item} key={item.id}>
              <View style={styles.nameNumber}>
            <Text style={styles.userName}>{userName}</Text>
            </View>
            <View style={styles.deleteButtonContainer}>
              <Button
                onPress={() => onDeleteContact(item.id)}
                >
              </Button>
            </View>
          </View>
        );
      },
    )}
  </View>
  );
};

我尝试在useEffect 中调用refetch。当我从主页来到whitelistscreen 时,它可以工作。但是,当我转到add contact屏幕,添加联系人然后导航回whitelist时,它不起作用。

也尝试在白名单中使用它:

useFocusEffect(
  React.useCallback(() => {
    console.log('refetching data');
    refetch();
  }, [])
);

每次我返回屏幕时它都会给我console.log('refetching data');,但 ui 没有更新,所以我猜它实际上并没有重新获取。

【问题讨论】:

  • console.log('component name') before return ( - 检查组件是否被渲染...如果是,更新/重新调整有问题
  • 我在白名单返回前添加了日志。如果我从这里导航到另一个屏幕然后返回,我应该会看到日志,但我看不到它。意味着不是每次都呈现数据。 @xadm
  • 那么这是更高级别的问题 - 管理视图/屏幕 - 使用的路由器?还原?
  • @xadm 暂时不使用 redux。导航使用来自@react-navigation/native'; 的 useNavigation。不知何故,日志现在可以工作了,所以它正在渲染但不重新获取
  • 也尝试使用 useFocusEffect 但这也不起作用。 @xadm

标签: javascript reactjs typescript graphql react-apollo


【解决方案1】:

您可以将钩子useUsersQuery 中的fetchPolicy 设置为cache-and-networknetwork-only,以便在访问该页面时更新用户列表页面。

cache-and-network

如果将fetchPolicy设置为cache-and-network,apollo会先显示缓存数据,并在后台进行网络调用更新缓存。收到响应后,它将更新缓存,进而重新渲染调用钩子的组件。当组件重新渲染时,用户列表将被更新。

优点:没有显示加载器。给人一种“快速网站”的印象。

缺点:在缓存更新之前会显示可能过时的数据(持续时间取决于查询解析的速度)。

这对于您不希望数据经常更改的页面很有用。如果添加/删除用户不是很频繁的操作,可以使用这个选项。

network-only

如果您将fetchPolicy 设置为network-only,apollo 将始终进行网络调用以获取数据。它永远不会将数据存储在其缓存中。

优点:保证显示最新数据。

缺点:需要在网络调用进行时显示加载程序。给人一种“网站速度慢”的印象。

如果在您的应用中添加/删除用户是一项频繁的操作,那么这是一个更好的选择,因为它可以确保始终显示最新的数据。

您可以在官方文档中阅读有关获取策略的更多信息 https://www.apollographql.com/docs/react/api/react-apollo/#optionsfetchpolicy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-22
    • 2021-12-27
    • 2018-06-11
    • 1970-01-01
    • 2020-04-27
    • 2018-07-15
    • 2023-01-06
    • 1970-01-01
    相关资源
    最近更新 更多