Vanilla MobX or MobX state tree are a good options to achieve something like this at scale. Alternatively, a small library like constate allows you to lift your hook return values into react context, as well as split return values into separate hooks for performance optimizations. Has definitely helped me a lot in avoiding redux and other state management libraries without too much heavy lifting and performance hits.
Anyways, nice job on the write up, always fun to see people exploring state management without redux