Skip to content

Instantly share code, notes, and snippets.

@AndreiCalazans
Created March 4, 2022 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndreiCalazans/8b9d55c08f55cc1a4d496b3940c4d605 to your computer and use it in GitHub Desktop.
Save AndreiCalazans/8b9d55c08f55cc1a4d496b3940c4d605 to your computer and use it in GitHub Desktop.
What's wrong with this FlatList.renderItem?
  const renderItem = useCallback(
    ({ item: { node } }) => {
      const slug = node.slug;
      const handlePress = () => {
        push('SignedOutAssetScreen', { assetSlug: slug });
      };

      return <MarketCell onPress={handlePress} key={node.uuid} asset={node} />;
    },
    [push],
  );

MarketCell is a memoized functional component - const MarketCell = memo((props) => ...);

Will MarketCell have re-renders or memo cache invalidations given its props?

The answer is yes

Why?

Because handlePress is unstable. A function defined inside the renderItem's useCallback will be recreated everytime renderItem is called.

This recreation causes memo's cache to be invalidated.

How do we solve this problem?

Good thing you asked. XD

To answer the question I want to argue that it is a good practice to avoid defining unmemoized inlined functions when your useCallback needs to return a component that consumes that callback.

So for our case we can wrap the MarketCell component in another component so we can make sure of useCallback for the onPress callback:

const Item = memo(
  ({ asset }: { asset: MarketCellProps['asset'] & { slug: string } }) => {
    const slug = asset.slug;
    const { push } = useStackNavigation();
    const handlePress = useCallback(() => {
      push('SignedOutAssetScreen', { assetSlug: slug });
    }, [slug, push]);

    return <MarketCell onPress={handlePress} asset={asset} />;
  },
);

changing the renderItem to:

  const renderItem = useCallback(({ item: { node } }) => {
    return <Item key={node.uuid} asset={node} />;
  }, []);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment