What is your biggest issue here?
The way the code looks with the deep nesting at the App level (I like Pipeline
and composeChildren
solutions already provided) or the cognetive overhead involved with understanding what does where?
Does the whole app need access to all of these seperate contexts?
Firstly, one provider in context would lead to the whole app re-rendering everytime the value of said context provider changes. Unless the app is very small this could have some noticable effects on user experience down the track and would not be worth the tradeoff for better looking code.
If I inherited this codebase, and the cognetive overhead, I would draw a diagram of the whole tree and mark out where each of these contexts are used. This would be a good way of starting to reduce the cognetive overhead you and give you some easier to understand context (pardon the pun) for how the app works.
If I had time to refactor and if the providers can wrap components further down the chain I would start with that. No use having a context wrap components at the app level if it's only used by a couple of leaf components.
Also, the aformentioned diagram could be added to the documentation somewhere along with some general rules for the context and where/how you want to use it. As annoying as this exercise would be at first it will give you a much better understanding of how the system as a whole works and there will be plenty of oppertunities for performance optimization.
Global state management in React is a difficult topic full of potential pitfalls and the pattern displayed here could easily see the whole app re rendering everytime a controlled input is used if you're not careful. Nadia Makrevich wrote a very good article on context and it's strengths and weaknesses if you have time to check it out:
https://www.developerway.com/posts/how-to-write-performant-react-apps-with-context
<App>
component itself should be pure, this tree will never re-render, and only dispatches from within the application will ever re-render specific context providers (and all their consumers, as it should), skipping re-rendering of the context providers which are nested within. – Artillery