0

I seem to always be fighting TypeScript. Can anyone tell me what I'm doing wrong here?

Argument of type '(old: number) => void' is not assignable to parameter of type 'number'
interface IPagination {
  pageNumber: number;
  setPageNumber: (num: number) => void;
  latestData: unknown;
}

Pagination.tsx

Updated to show for the Pagination component

const Pagination: React.FC<IPagination> = (props: IPagination) => {
  const { pageNumber, setPageNumber, latestData } = props;

  return (
    <>
      <button
        disabled={pageNumber === 1}
        onClick={() => setPageNumber((old: number) => Math.max(old - 1, 1))}
      >
        {strings.PREVIOUS}
      </button>
      <span>{pageNumber}</span>
      <button
        disabled={!latestData || !latestData.next}
        onClick={() =>
          setPageNumber((old) =>
            !latestData || !latestData.next ? old : old + 1
          )
        }
      >
        {strings.NEXT}
      </button>
    </>
  );
};
pingeyeg
  • 632
  • 2
  • 6
  • 23

1 Answers1

1

Assuming setPageNumber is a state-setting function passed in from a useState hook in the parent, the correct type for it is not (num: number) => void, but rather React.Dispatch<React.SetStateAction<number>>, which expands to (value: React.SetStateAction<number>) => void.

React.SetStateAction<number>, in turn, expands to number | ((prevState: number) => number). So the final type for setPageNumber is

(value: number | ((prevState: number) => number)) => void
Lionel Rowe
  • 5,164
  • 1
  • 14
  • 27
  • Ok, based on this response, it would seem sending state-setting functions is bad practice. Maybe I'm wrong. setPageNumber is a useState hook. – pingeyeg Feb 10 '21 at 15:14
  • I never said anything about it being a bad practice. It's a common and reasonable way of controlling parent state from a child. It's only a bad practice if you're passing the function through several layers of components - in that case you'd be better off using a [Context](https://reactjs.org/docs/hooks-reference.html#usecontext). Just make sure to annotate it with the correct type (`Dispatch>`) in your prop types. – Lionel Rowe Feb 10 '21 at 18:41