React useMemo missing dependency

Viewed 1402
  const handleTestDelete = (id: any) => {
    deleteTest(id).then(() => {
      queryClient.invalidateQueries("test");
    });
  };

  const columns = useMemo(
    () => [
      { field: "id", headerName: "ID", width: 80 },
      {
        field: "",
        width: 120,
        disableClickEventBubbling: true,
        sortable: false,
        disableColumnMenu: true,
        renderCell: (cell: any) => (
          <>
            <IconButton
              aria-label="delete"
              onClick={() => handleTestDelete(cell.id)}
            >
              <DeleteIcon fontSize="small" />
            </IconButton>
            <IconButton
              aria-label="view"
              onClick={() => history.push(`/something/${cell.id}/details`)}
            >
              <VisibilityIcon fontSize="small" />
            </IconButton>
          </>
        ),
      },
    ],
    [history]

I am getting this warning

React Hook useMemo has a missing dependency: 'handleTestDelete'. Either include it or remove the dependency array.

because I am not adding the function called on click of the delete button in dependencies ... why should I put it as a dependency? I'm not even sure if putting history as a dependency is correct; I don't think columns need to be reevaluated when chronology changes

I was wrong?

Thank you

1 Answers

If you are using useMemo, you should satisfy its dependencies as the suggested by eslint-plugin-react-hooks:

const history = useHistory()

const columns = useMemo(() => {
  console.log("define memoized columns") // Log 1
  return [
    { field: 'id', headerName: 'ID', width: 80 },
    {
      // ... code here
      renderCell: (cell: any) => (
        <>
          <IconButton
            aria-label="delete"
            onClick={() => handleTestDelete(cell.id)}
          >
            <DeleteIcon fontSize="small" />
          </IconButton>
          <IconButton
            aria-label="view"
            onClick={() => history.push(`/something/${cell.id}/details`)}
          >
            <VisibilityIcon fontSize="small" />
          </IconButton>
        </>
      ),
    },
  ]
}, [history, handleTestDelete])

Using history would be safe because it won't change (unless it is changed in React Router's context which is unlikely in this example). And, you would need to wrap that function in a useCallback:

const handleTestDelete = useCallback((id: any) => {
  deleteTest(id).then(() => {
    queryClient.invalidateQueries('test')
  })
}, []) // <---- Here, you need to add the dependencies as well (maybe queryClient)

You may have one more option here: Remove handleTestDelete from the useMemo's dependencies and define the handleTestDelete function inside the useMemo; before returning the memoized columns.

Note: As I don't see your complete code, I would suggest that you test this code and make sure that the Log 1 in useMemo is printed appropriately (only once).


Similar posts:

Related