debounce(getData(), 2000);
То есть, за как минимум четыре с половиной года занятий программированием вы не научились различать собственно функцию и результат её вызова. Ну тут только рукой махнуть, случай безнадёжный.
Кроме того, debounced функция при каждом рендере компонента должна быть одна и та же, так что завернём её в useCallback, а чтобы она использовала актуальное состояние, будем передавать его как параметр:
const getData = useCallback(debounce(query => {
/*
* здесь всё по-старому, кроме body: JSON.stringify({ query: state.query }),
* надо заменить на body: JSON.stringify({ query }),
*/
}, 2000), []);
useEffect(() => {
getData(state.query);
}, [ state.query ]);