We also created associated custom hooks that allow developers to easily "inject" a service into their React component (we use React's Context API for our "DI container").
From there developers can read the service state to drive the look of the UI, or send events to it to trigger behaviour that is encapsulated in the service itself.
Our most used service is a UserSession service that manages OAuth based login flow and session management.
The best part of this approach is that our service layer started in an Angular based proof-of-concept before we lifted-and-shifted it all into React.