Я не буду ручаться за точность своего описания, но стейт менеджер работает примерно так.
Есть стейт, есть действия(actions), есть редьюсер. Диспатч нужен, чтобы отправить конкретный экшн редьюсеру. Когда ты вызываешь диспатч и в параметрах передаешь ему экшн - этот экшн обрабатывается редьюсером и редьюсер должен вернуть новый стейт. Это про однонаправленный поток данный,
flux и вот это вот все.
А вот ты комментируешь вызов диспатча - и все, ты не отправляешь никуда свой экшн, редьюсер не вызывается - стейт не меняется(не заменяется новым объектом). То есть ты не совершаешь вот тот вот однонаправленный поток данных и нарушаешь логику использования реакта и стейт-менеджера.
А то, что ты где-то получил доступ к объекту стейта и мутировал его - так стейт остался тем же объектом, что и был, изменилось только его внутреннее состояние. В то время как реакт вызывает render() только если получил другой объект.
// как бы разница вот в этом
a = {a:1}
b = {a: 1}
Boolean(a === a) // true
Boolean(a === b) // false
c = a
a = {...a}
Boolean(a === c) // false