Проблема была в CORS.
Сначала отвергал это решение в связи с тем, что без useEffect всё работало, но добавление заголовков CORS в ответ сервера исправило ситуацию.
Если кто сможет объяснить, почему именно при вызове fetch() через useEffect возникла проблема с CORS, был бы рад.