Search code examples
reactjsfunctionrerenderusecallback

why component re-render again even with useCallback?


I have a User Page that fetch the user info with a custom hook useFetchUserId(). This custom hook uses useEffect to fetch the data, and has a console.log that is printed every time I switch between tabs, even if I use the useCallback hook. Can you explain why, and how to fix it?

UserProfile page:

  const location = useLocation();
  const userId = location.state?.userId;
  const [tab, setTab] = useState("1");
  const { user, loading } = useFetchUserId(userId);

  const handleTabChange = useCallback(function handleTabChange(event, newTab) {
    setTab(newTab);
  }, []);

  return (
          <TabList onChange={handleTabChange} aria-label="lab API tabs example">
            <Tab label="Info" value="1" />
            <Tab label="Cambia Password" value="2" />
            <Tab label="Curriculum" value="3" />
          </TabList>
        

useFetchUserId:

 export const useFetchUserId = (id) => {
  const [user, setUser] = useState([]);
  const [loading, setLoading] = useState(false);
  console.log("fetch  " + id);

  useEffect(() => {
    const fetch = async () => {

      try {
        const response = await axios....
        const result = response?.data;
        if (result) {
          setUser(result);
        }
      } catch (err) {
        console.log(err);
      } 
    };
    fetch();
    
  }, []);

  return { user, loading };
};

Solution

  • You change state by setTab(newTab). It triggers re-render (aka re-execution of component function). This way your hook useFetchUserId is executed every time. This is why you see a console log multiple times. See the console.log outside of useEffect.