Если попробовать поразмышлять..
useState подразумевает плюс-минус простой стейт, который удобно обновлять через либо setState(newValue), либо через setState(prevState => ({ ...prevState, key: newValue })).
useReducer для более сложных кейсов, где хранить логику обновления в компоненте становится нецелесообразным и/или будет слишком раздуваться компонент. Или же где логика переиспользуется. Впрочем, то же самое можно сделать и через useState, создав свои хуки, которые под капотом юзают useState/useReducer.
На выходе, самым логичным на ум приходит более плавная миграция в redux на useReducer.
Проблема в том, что redux не нужен в 90%+ проектах, и его можно было заменить голым реактом с его инструментами.