refetchQueries只对某些查询有效[英] refetchQueries works for only some queries

本文是小编为大家收集整理的关于refetchQueries只对某些查询有效的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我在我的AllFriends屏幕上使用Friend组件,该突变:

  const [deleteUserRelation] = useDeleteUserRelationMutation({
    onCompleted: () => {
      Alert.alert('Unfriended');
    },
    refetchQueries: [{ query: GetMyProfileDocument }],
    awaitRefetchQueries: true,
    onError: _onDeleteUserRelationError,
  });

每次突变都成功,查询会得到彻底进行,并且此处的数据已成功渲染.我还看到了必要的日志.

export const AllFriends: React.FunctionComponent = () => {
  const navigation = useNavigation();

  const { data, error } = useGetMyProfileQuery(
    {
      onCompleted: () => {
        console.log('from all friends')
      }
    }
  );
  return (
    <SafeAreaView style={styles.safeView}>
      <Container style={styles.container}>
        <View style={styles.listHolder}>
          {data && (
            <FlatList
              data={data.me.friends.nodes}
              horizontal={false}
              renderItem={({ item }) => (
                <Friend friend={item} originatorId={data.me.id} numberOfFriends={item.friends.totalCount}/>
              )}
              keyExtractor={(item) => item.id.toString()}
            />
          )}
        </View>
      </Container>
    </SafeAreaView>
  );
};

但是,我在此处使用相同的查询,但是此处没有进行拆除,因此没有重新渲染组件,因此在此不反映更改.我在这里也看不到迎面值的日志.我错过了什么?

export const WhitelistBar: React.FC = () => {
  const [friendList, setFriendList] = useState<Friend[]>();
  const [originatorId, setOriginatorId] = useState<number>();

  const _onCompleted = (data) => {
    console.log('running', data);
    let DATA = data.me.friends.nodes.map(
      (item: {
        id: number;
      }) => ({
        id: item.id,
        imageUrl: defaultUrl,     
      }),
    );
    setFriendList(DATA);
    console.log('daattaaa', DATA);
    setOriginatorId(data.me.id)
  };

  const _onError = () => {
    let DATA = [
      {
        id: 1,
        imageUrl: defaultUrl,
        name: 'Friend',
      },
      {
        id: 2,
        imageUrl: defaultUrl,
        name: 'Friend',
      },
    ];
    setFriendList(DATA);
    setOriginatorId(0);
  };

  const { data } = useGetMyProfileQuery({
    variables: {},
    onCompleted: _onCompleted,
    onError: _onError,
  });


  return (
    <View style={scaledStyles.container}>
      <View style={scaledStyles.whiteListBarTitle}>
        <Text style={scaledStyles.whiteListBarText}>Meine Freunde</Text>
        <Text
          style={[scaledStyles.whiteListBarText, { color: 'grey' }]}
          onPress={() => navigation.navigate('AllFriends')}>
          Alle Anzeigen
        </Text>
      </View>
      <View style={{ flexDirection: 'row' }}>
        <WhitelistItem title={ADDICON.name} face={ADDICON.imageUrl}/>
        <FlatList
          showsHorizontalScrollIndicator={false}
          data={friendList}
          horizontal={true}
          scrollEnabled
          renderItem={({ item }) => (
            <WhitelistItem
              title={item.name}
              face={item.imageUrl}
              firstName={item.name}
            />
          )}
          keyExtractor={(item) => item.id.toString()}
        />
      </View>
    </View>
  );
};

推荐答案

我看不到您的useGetMyProfileQuery钩子,但我想问题是提取策略.
在useQuery选项中设置fetchPolicy: "network-only".

  const { data } = useGetMyProfileQuery({
    variables: {},
    fetchPolicy: "network-only",
    onCompleted: _onCompleted,
    onError: _onError,
  });

如果提取物是"仅缓存"或"高速缓存",则首次将获得缓存的数据.似乎您已经缓存了数据,因为在其他屏幕上也使用了数据.
默认情况下是"cache-first"

本文地址:https://www.itbaoku.cn/post/1938042.html

问题描述

I use a Friendcomponent on my AllFriends screen that runs this mutation:

  const [deleteUserRelation] = useDeleteUserRelationMutation({
    onCompleted: () => {
      Alert.alert('Unfriended');
    },
    refetchQueries: [{ query: GetMyProfileDocument }],
    awaitRefetchQueries: true,
    onError: _onDeleteUserRelationError,
  });

Every time, the mutation is successful, the query is refetched and data here is successfully re-rendered. I also see the necessary logs.

export const AllFriends: React.FunctionComponent = () => {
  const navigation = useNavigation();

  const { data, error } = useGetMyProfileQuery(
    {
      onCompleted: () => {
        console.log('from all friends')
      }
    }
  );
  return (
    <SafeAreaView style={styles.safeView}>
      <Container style={styles.container}>
        <View style={styles.listHolder}>
          {data && (
            <FlatList
              data={data.me.friends.nodes}
              horizontal={false}
              renderItem={({ item }) => (
                <Friend friend={item} originatorId={data.me.id} numberOfFriends={item.friends.totalCount}/>
              )}
              keyExtractor={(item) => item.id.toString()}
            />
          )}
        </View>
      </Container>
    </SafeAreaView>
  );
};

However, I am using the same query here but the data is not refetched here and hence the component is not re-rendered so the changes aren't reflected here. I don't see the onCompleted logs here as well. What am I missing out?

export const WhitelistBar: React.FC = () => {
  const [friendList, setFriendList] = useState<Friend[]>();
  const [originatorId, setOriginatorId] = useState<number>();

  const _onCompleted = (data) => {
    console.log('running', data);
    let DATA = data.me.friends.nodes.map(
      (item: {
        id: number;
      }) => ({
        id: item.id,
        imageUrl: defaultUrl,     
      }),
    );
    setFriendList(DATA);
    console.log('daattaaa', DATA);
    setOriginatorId(data.me.id)
  };

  const _onError = () => {
    let DATA = [
      {
        id: 1,
        imageUrl: defaultUrl,
        name: 'Friend',
      },
      {
        id: 2,
        imageUrl: defaultUrl,
        name: 'Friend',
      },
    ];
    setFriendList(DATA);
    setOriginatorId(0);
  };

  const { data } = useGetMyProfileQuery({
    variables: {},
    onCompleted: _onCompleted,
    onError: _onError,
  });


  return (
    <View style={scaledStyles.container}>
      <View style={scaledStyles.whiteListBarTitle}>
        <Text style={scaledStyles.whiteListBarText}>Meine Freunde</Text>
        <Text
          style={[scaledStyles.whiteListBarText, { color: 'grey' }]}
          onPress={() => navigation.navigate('AllFriends')}>
          Alle Anzeigen
        </Text>
      </View>
      <View style={{ flexDirection: 'row' }}>
        <WhitelistItem title={ADDICON.name} face={ADDICON.imageUrl}/>
        <FlatList
          showsHorizontalScrollIndicator={false}
          data={friendList}
          horizontal={true}
          scrollEnabled
          renderItem={({ item }) => (
            <WhitelistItem
              title={item.name}
              face={item.imageUrl}
              firstName={item.name}
            />
          )}
          keyExtractor={(item) => item.id.toString()}
        />
      </View>
    </View>
  );
};

推荐答案

I can't see your useGetMyProfileQuery hook, but I guess the issue is with the fetch policy.
Set the fetchPolicy: "network-only" in the useQueryoptions.

  const { data } = useGetMyProfileQuery({
    variables: {},
    fetchPolicy: "network-only",
    onCompleted: _onCompleted,
    onError: _onError,
  });

If the fetchPolicy is "cache-only" or "cache-first", than the cached data will be fetched for the first time. And seems like you have cached data, because have used it also at other screens.
By default it's "cache-first"