Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

171
Views
React - useCallback vs useMemo for JSX elements

I have implemented this component:

function CardList({
  data = [],
  isLoading = false,
  ListHeaderComponent,
  ListEmptyComponent,
  ...props
}) {
  const keyExtractor = useCallback(({ id }) => id, []);

  const renderItem = useCallback(
    ({ item, index }) => (
      <Card
        data={item}
        onLayout={(event) => {
          itemHeights.current[index] = event.nativeEvent.layout.height;
        }}
      />
    ),
    []
  );

  const renderFooter = useCallback(() => {
    if (!isLoading) return null;

    return (
      <View style={globalStyles.listFooter}>
        <Loading />
      </View>
    );
  }, [isLoading]);

  return (
    <FlatList
      {...props}
      data={data}
      keyExtractor={keyExtractor}
      renderItem={renderItem}
      ListHeaderComponent={ListHeaderComponent}
      ListFooterComponent={renderFooter()}
      ListEmptyComponent={ListEmptyComponent}
    />
  );
}

As my CardList component is heavy, I have tried to optimize it following these tips.

But, I think that instead of using useCallback for renderFooter, I should use useMemo, in order to memoize the resulted JSX and not the method:

const ListFooterComponent = useMemo(() => {
  if (!isLoading) return null;

  return (
    <View style={globalStyles.listFooter}>
      <Loading />
    </View>
  );
}, [isLoading]);

Am I correct?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

If you want to avoid expensive calculations use useMemo. useCallback is for memoizing a callback/function.

Official docs do have an example of using useMemo with JSX for avoiding re render:

function Parent({ a, b }) {
  // Only re-rendered if `a` changes:
  const child1 = useMemo(() => <Child1 a={a} />, [a]);
  // Only re-rendered if `b` changes:
  const child2 = useMemo(() => <Child2 b={b} />, [b]);
  return (
    <>
      {child1}
      {child2}
    </>
  )
}

Personal observation:

But to be more detailed, it seems it is not that useMemo here magically prevents re render, but the fact that you render same reference on the same spot in component hierarchy, makes react skip re render.

Here:

let Child = (props) => {
  console.log('rendered', props.name);

  return <div>Child</div>;
};

export default function Parent() {
  let [a, setA] = React.useState(0);
  let [b, setB] = React.useState(0);

  // Only re-rendered if `a` changes:
  const child1 = React.useMemo(() => <Child a={a} name="a" />, [a]);
  // Only re-rendered if `b` changes:
  const child2 = React.useMemo(() => <Child b={b} name="b" />, [b]);

  return (
    <div
      onClick={() => {
        setA(a + 1);
      }}
    >
      {a % 2 == 0 ? child2 : child1}
    </div>
  );
}

If you keep clicking the div you can see it still prints "rendered b" even though we never changed the b prop. This is because react is receiving a different reference each time inside the div, and doesn't optimize the re render - like it does if you had simply rendered only child2 without that condition and child1.

Note: The fact that react skips rendering when it receives same element reference in the same spot is known, so apparently useMemo technique works because of that when it comes to rendering optimization.

about 4 years ago · Juan Pablo Isaza Report

0

"Should" is a matter of opinion, but you certainly can. React elements are fully reusable. It's not likely to make any real difference to your component, though, since creating the elements is fast and renderFooter is just used immediately in a component that's already running (unlike keyExtractor and renderItem, which you're passing to FlatList, so you want to make them stable where possible so FlatList can optimize its re-rendering). But you certainly can do that.

about 4 years ago · Juan Pablo Isaza Report

0

useMemo is perfectly sensible here as it memoizes the result (the JSX). As you say, useCallback memoizes the function not the result.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!