React Updatable Context
Allow to easily update React context Provider value, directly from the consumer.
This makes the Provider stateful.
yarn add react-updatable-context
npm install react-updatable-context
Examples
Let's first define a very simple language selector component, and in the following examples we'll see how to connect this stateless component to our context.
const LanguageSelector = language updateLanguage <div> <div>Current language: language</div> <div =>Switch to french</div> <div =>Switch to english</div> </div>;
Simple example
import createUpdatableContext from 'react-updatable-context'; const Provider: LanguageProvider Consumer: LanguageConsumer = ; // Add the provider to your app like with normal Context apiconst MyApp = <LanguageProvider = = > <Router/> </LanguageProvider>; // Use the consumer like normal Context api, but it also receives a 2nd parameterconst AppLanguageSelector = <LanguageConsumer> value update <LanguageSelector = = /> </LanguageConsumer>
Managing your global app state with Context
Sometimes the level of indirection with events/actions, and tools like Redux, is too much. Using a simple global state API on top of Context can be good enough for many apps.
But... We don't want to expose the state structure to deeply nested components.
createSubConsumer
and connect
are here for that.
import createUpdatableContext from 'react-updatable-context'; const Provider Consumer createSubConsumer connect } = ; const MyApp = <Provider = > <Router/> </Provider>; // Then you can use the global consumer directly, but your component is aware of the global state structureconst AppLanguageSelector = <Consumer> value update <LanguageSelector = = /> </Consumer>; // You can use a "sub consumer" which will refine the value/update api so that you can only get/set the languageconst LanguageConsumer = ; // Then you can write this instead, which expose less internal state structureconst AppLanguageSelector = <LanguageConsumer> value update <LanguageSelector = = /> </LanguageConsumer>; // You can also use `connect` if you prefer HOCs and an API similar to react-reduxconst AppLanguageSelector = LanguageSelector
Performance and pure components
For performance reasons, we want to inject stable callbacks when connecting to components.
On every global state changes, all the consumers will be invoked, and we don't want pure components that consume only a small amount of state to render unnecessarily.
For that, it is possible to create the callbacks only once, at creation time.
Somehow, you are defining an update API that will replace the raw low-level update API that is injected as the 2nd arg of the consumer
const // ... connect } = ; // Then you can connect with a stable callback:const AppLanguageSelector = LanguageSelector // Or with a sub-consumerconst LanguageConsumer = ;
Advanced: using a reducer
TODO reducer/dispatch example
TODO
- Complete examples
- Support updates with a function (like
setState(oldState => newState)
)