Home > Software design >  react-native : how to sort data before screen is drawn?
react-native : how to sort data before screen is drawn?

Time:07-16

I call data by using useQuery and gql.

const SEE_ALL_FEED_ORDER = gql`
  query seeAllFeedOrder {
    seeAllFeedOrder {
      id
      name
      avatar
      directFeedNumber
    }
  }
`;

  const { data: allFeedData, loading: allFeedDataLoading, 
refetch: allFeedRefetch } = useQuery(SEE_ALL_FEED_ORDER);

I named result data as allFeedData as above. And I need to sort this allFeedData before screen is shown up.

So I use useEffect and useState.

  const [flatlistdata, setFlatlistdata] = useState([]);

  useEffect(() => {
    if (!allFeedDataLoading) {
      setFlatlistdata(
        [...allFeedData.seeAllFeedOrder].sort(function (a, b) {
          return b.directFeedNumber - a.directFeedNumber;
        })
      );
    }
  }, []);

So if this query loading is finished, then I put sorted data to flatlistdata by using setFlatlistdata.

And with this flatlistdata, I run flatlist.

  <FlatList
    data={flatlistdata}
    keyExtractor={(item) => item.id}
    renderItem={RankRow}
    refreshing={refreshing}
    onRefresh={refresh}
  />

But when I click screen, undefined is not an object(evaluating 'allFeedData.seeAllFeedOrder' error comes.

which means I couldn't call allFeedData. I think this might happen screen is drawn before data is sorted? is that right?

So I also give condition to Flatlist as below.

flatlistdata === [] ? (
    <View>
      <ActivityIndicator size={30}></ActivityIndicator>
    </View>
  ) : 
      <FlatList
        data={flatlistdata}
        keyExtractor={(item) => item.id}
        renderItem={RankRow}
        refreshing={refreshing}
        onRefresh={refresh}
      /> }

or

allFeedDataLoading ? (
    <View>
      <ActivityIndicator size={30}></ActivityIndicator>
    </View>
  ) : 
      <FlatList
        data={flatlistdata}
        keyExtractor={(item) => item.id}
        renderItem={RankRow}
        refreshing={refreshing}
        onRefresh={refresh}
      /> }

I intended to draw ActivityIndicator screen first before data is sorted and put to flatlistdata and then proper screen show up, but it throws same error.

What is the problem? and how can I fix this ?

CodePudding user response:

So I use useEffect and useState.

why would you need that? the sorted data is derived state that doesn't need to be managed separately:

const { data: allFeedData } = useQuery(SEE_ALL_FEED_ORDER);

const sortedData = allFeedData ? [...allFeedData.seeAllFeedOrder].sort(...) : []

then just pass sortedData to the FlatList. If it turns out that sorting is slow or that referential identity is important, you can wrap the sorting in useMemo. I also have a blog post on this topic: https://tkdodo.eu/blog/dont-over-use-state

  • Related