State, in this context, is just the read/write data that a UI project like a React app needs. State management is about avoiding making a mess of this data when you have a complex component hierarchy with some distantly related components that need to read/modify the same part of state.
Suppose you have an app whose component hierarchy looks like this:
Without a state management framework, if you wanted to make it so that the AddBlogBtn
adds a new blog that is then rendered in BlogList
, youâd have to bubble up the event up to a common ancestor of AddBlogBtn
and BlogList
and then have new props be passed down to BlogList
.
In this example, itâs not so bad, but when the component hierarchy is much larger (which it often is in practice), then the âsharingâ and manipulation of common state between very distant relatives in the component tree quickly becomes complex because youâd have to pass data through many layers, across components that donât actually need that data, just to get that data to the component that needs it which is further down in the tree. This problem is called âprop drillingâ. This is a very common problem in UI projects and so there exists many different strategies for avoiding this, each with their own tradeoffs to consider (which usually include short-term productivity vs. long-term productivity, elegance vs. comprehensiveness, etc.).
Broadly, those strategies are:
- Flux (eg. through Vuex).
- Redux (eg. through React Redux).
- React Context.
Redux, for example, centralises the appâs state by extracting out all the main parts of state into a global âstoreâ and allows all components, regardless of where they are in the hierarchy, to read/write to that store. Any updates to the shared global state made by one component are immediately âreceivedâ by other components dependent on the part of the global state that was updated.