Modifying global state is not bad. When you have a database, you want to modify it's state at some point, right? In the frontend you could use the same analogy. It's not that you don't want to mutate state. You just want to contain and control these mutations. You want the mutations to happen exactly whre you want them, and nowhere else.
It's all about control. If you define a strict protocol to mutate state (like inside some named structure, like actions) and forbid every mutation outside the protocol, you are taking control of how your state will change. This lead to predictable code and meaningful state transitions.
Instead of having a lot of components fighting to change state and producing unpredictable results, you have them calling actions. These actions are simple atomic mutations that makes sense! Example:
REQUEST_LOGIN
LOGIN_OK
REQUEST_CURRENT_USER
RECEIVE_CURRENT_USER
You see these actions firing. You know exactly what's happening and where to solve your problems. That's the whole point. It's even easier to test code like this.