简体   繁体   中英

Should I add useCallback or useMemo to my effect?

The following tooltip will call the API once the user hovers on a button. I wonder if I need to work with useCallback or useMemo to avoid unnecessary API calls? I still struggle to understand when I need one of the two. If it makes sense to add it, how would you do it?

const ProfileTooltip = ({ children, userId }) => {
    const classes = useStyles();
    const [open, setOpen] = useState(false);
    const [profileInfo, setProfileInfo] = useState(false);
  
    useEffect(() => {
      if (!open) {
        return;
      }
  
      const fetchProfileInfo = async () => {
        try {
          const { data } = await api.get(`users/${userId}/info/`);
          setProfileInfo(data);
        } catch (e) {
          setProfileInfo(null);
        }
      };
      fetchProfileInfo();
    }, [open, userId]);
  
    const handleOpen = () => {
      setOpen(true);
    };
  
    const handleClose = () => {
      setOpen(false);
    };
  
    const renderTooltip = () => {
      if (!profileInfo) {
        return;
      }
  
      return (
        <>
          <h3 className={classes.profileName}>
            {profileInfo.firstName} {profileInfo.lastName}
          </h3>
          <p className={classes.headline}>{profileInfo.headline}</p>
          <Button size="small" variant="contained" color="primary" fullWidth>
            Message
          </Button>
        </>
      );
    };
  
    return (
      <div className={classes.root}>
        <Tooltip
          arrow
          classes={{
            tooltip: classes.tooltip,
            arrow: classes.arrow,
            tooltipArrow: classes.tooltipArrow,
            popperArrow: classes.popperArrow,
          }}
          interactive
          placement="top-start"
          onOpen={handleOpen}
          onClose={handleClose}
          title={renderTooltip()}
        >
          {children}
        </Tooltip>
      </div>
    );
  };
  
  export default ProfileTooltip;

useCallback hook is used to memoize callback functions so that they are not re-created every time component re-renders. This is useful when you want to pass a function to a child component and that child component depends on reference equality to avoid unnecessary re-renders.

useMemo hook is used to memoize values to avoid doing expensive computations on every render of the component. Function passed to useMemo runs during rendering, so any code that has side effects should not be written in this function.

I wonder if I need to work with useCallback or useMemo to avoid unnecessary API calls?

Both these hooks won't help in your case.

Side effects such as API calls belong in useEffect hook and to optimize the execution of your side effect, you will need to look at the dependency array of the useEffect hook.

You could, however, wrap handleOpen and handleClose functions in useCallback hook. Doing this will prevent re-creating these functions on every render and a memoized function reference will be passed to Tooltip component.

You will need to make sure that you get the dependency array of useCallback hook right otherwise you will run into bugs that could be hard to debug.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM