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

346
Views
React: to useCallback or define in inner component?

I have two components, such that they are:

const ChildOn = (/*...*/) => {
  //...
}

const Parent = () => {
  const [is42, setIs42] = useState(true)

  return (is42 ? <ChildOff ... > : <ChildOn ... />)
}

The definition of ChildOff is no important.

I want to define them as either of the following, yet I can't decide which:

  1. Declares functions used in children, based on a variable/function in the parent, inside each child.

    type ChildOnProp = { setIs42: Dispatch<SetStateAction<boolean>> };
    const ChildOn = ({ setIs42 }: ChildOnProp) => {
      const f1 = () => { setIs42(true); };
      return <Text onPress={f1} />;
    };
    
    const Parent = () => {
      return is42 
        ? <ChildOff setIs42={setIs42} /> 
        : <ChildOn setIs42={setIs42} />;
    };
    
  2. Defines functions used by children, inside the parent.

    type ChildOnProps = { func: () => void }
    const ChildOn = ({ func }: ChildOnProps) => {
      return <Text onPress={func} />
    }
    
    const Parent = () => {
      const [is42, setIs42] = useState(true)
      const f1 = useCallback(() => { setIs42(true) })
      const f2 = useCallback(() => { setIs42(false) })
      return (is42 ? <ChildOff func={f2} /> : <ChildOn func={f1} />)
    }
    

While (1) is much prettier to me, (2) seems a lot more efficient. Yet I don't know if I'm apt to judge that, since I've read many articles on React contradicting each other on when it's best to use useCallback.

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

0

The React community warns against useless memoizing as it could add complexity without any of the benefits in some situations.

In this case, I think it's worth memoizing the callbacks since it will reduce the number of unnecessary renders of the child components, which otherwise could have negative impact, or even introduce issues down over time.

To do this, there's a common pattern of creating a custom hook, often called useToggle, which memoize common setters.

import {useState, useMemo} from 'react';

export function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);

  // Defined once, so guaranteed stability
  const setters = useMemo(() => ({
    toggle: () => setValue(v => !v),
    setFalse: () => setValue(false),
    setTrue: () => setValue(true),
    setValue,
  }), [setValue]);

  // Defined each time the value changes, so less than every render.
  return useMemo(() => ({
    ...setters,
    value
  }), [value, setters]);
}

This can be used in the parent as such:

const Parent = () => {
  const { value: is42, setTrue, setFalse } = useToggle(true);
  return (is42 ? <ChildOff func={setFalse}> : <ChildOn func={setTrue} />);
}

TypeScript will infer all the types automatically, so it works out of the box.


If there's multiple state values that need a toggle callback, we can easily identify each one by not destructuring.

const firstState = useToggle(true);
const secondState = useToggle(true);
//...
return (
  <>
    <Foo onClick={firstState.toggle} />
    <Bar onClick={secondState.toggle} />
  </>
);

As a reference, here's a simpler implementation from Shopify. As for memoizing too much or too little, Meta (Facebook) is apparently experimenting with memoizing everything by default at transpile time, so that devs wouldn't have to think about it.

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!