每次进入屏幕时刷新数据

时间:2020-06-10 18:19:39

标签: javascript reactjs typescript graphql react-apollo

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

但是,我有AddContact的另一个组件,它实际上并未链接到Whitelist组件(导航除外)。因此,当我添加用户并返回到Whitelist屏幕时,用户界面不会更新。没有呈现新用户。每次重新访问Whitelist屏幕时,有什么方法可以调用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>
  );
};

我尝试在refetch中呼叫useEffect。当我从首页转到whitelist屏幕时,它可以工作。但是,当我进入add contact屏幕,添加联系人然后导航回到whitelist时,此方法不起作用。

也尝试在白名单中使用此功能

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

每次返回屏幕时,它都会为我提供console.log('refetching data');,但是ui并未更新,因此我猜测它实际上并未被重新提取。

1 个答案:

答案 0 :(得分:1)

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

cache-and-network

如果将fetchPolicy设置为cache-and-network,则apollo将首先显示缓存的数据,并在后台进行网络调用以更新缓存。收到响应后,它将更新缓存,这将重新渲染调用该挂钩的组件。重新提供组件后,用户列表将被更新。

优点:未显示加载程序。给人以“快速访问”的印象。

缺点:显示可能过时的数据,直到更新缓存为止(持续时间取决于查询的解析速度)。

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

network-only

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

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

缺点:网络通话进行时,需要显示加载程序。给人“慢点”的印象。

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

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