skip to Main Content

i have a doubt about React hook, his props and useEffect.

In my component, i receive a list inside props, i must filter the received list and get a value from the list before the component is mounted.

(this code is a simplified example, i apply another filters and conditions more complex)

function MyComponent(props) {
  const [value, setValue] = useState(null)

  useEffect(()=>{
    var found = props.myList.find((x)=> {return x.name=="TEST"});

    if(found.length > 0)
        setValue("Hello World")
  }, []);

  return (
   <div>{value}</div>
  )
}

Is correct to use useEffect for get and set a value respect to props before the component is mounted?

3

Answers


  1. There’s no need to use useEffect here, you can simply pass a callback to the useState hook. The callback is only ran on the initialization of the hook so this has the same outcome as your useEffect hook (i.e. it doesn’t run on every rerender so same performance hit).

    function MyComponent({ myList }) {
      const [value, setValue] = useState(() => {
        const found = myList.find(x => x.name === 'TEST');
    
        return found ? 'Hello World' : null;
      });
    
      return (
        <div>{value}</div>
      );
    }
    
    Login or Signup to reply.
  2. This useEffect is executed after the 1st render, so null would be "rendered" first, and then the useEffect would update the state causing another render.

    However, if your value is dependent on the props, and maybe on other states (filters for example), this is a derived value, and it doesn’t need to be used as a state. Instead calculate it on each render, and if it’s a heavy computation that won’t change on every render wrap it with useMemo:

    function MyComponent({ myList }) {
      const value = useMemo(() => {
        const found = myList.some(x => x.name=="TEST");
      
        return found ? 'Hello World' : '';
      }, [myList]);
    
      return (
       <div>{value}</div>
      )
    }
    
    Login or Signup to reply.
  3. No need for any hook at all, actually, you should just write it like this:

    function MyComponent({ myList }) {
      const found = myList.some(x => x.name == "TEST");
      const value = found ? 'Hello World' : '';
    
      return (
       <div>{value}</div>
      )
    }
    

    Using useEffect or even only useState is conceptually wrong. The useState hook is used when a component needs to have its own independent internal state which isn’t the case here, as the value is purely derived from the props. The useEffect hook is an escape hatch typically used when you need to sync with some external imperative API, not at all the case here.

    The solution with useMemo is perfectly fine, and more efficient if your filtering condition is very computationally expensive, but it is also a lot more complicated to understand and to maintain, so I would suggest going for the simplest solution until the lack of memoization actually becomes a measurable problem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search