The purpose is reactivity: when X state changes, Y needs to update. How do we know which Y's care about which Xes? How do we initialize and clean up those associations as Xes and Y's get created and destroyed? How do we make sure X can't be mutated without triggering Y to update and stay in sync?
This is necessary on the web because it doesn't operate in immediate-mode. React, despite its name, doesn't actually solve the reactivity problem (well, setState and hooks kind of do, but they're pretty basic). The big deal with "state management libraries" like Redux and MobX is that they give you an enshrined container of state that knows how to publish its changes to the things that care about it, in a way that's more performant and ergonomic than the naive approach. That comes with different caveats and constraints depending on the library you choose.
You mentioned events, which can be part of a solution (just like regular callbacks can), but they don't actually solve the hard part of the problem.