react-binding-context
v1.0.0
Published
a performant react context
Downloads
4
Maintainers
Readme
react-lightning-context
A super performant lightning fast context library that only re-renders what has changed and nothing else. This library is a drop in replacement of the official React Context
and it is only 12kb!!!!
Why ?
When building web apps at scale one of the main problems is performance over time. When you have 20+ multiple teams contributing to a same code base it is impossible to not hit this bottleneck. This library tries to mitigate some of this problem by providing a Context API
that is reliant ant performant. It tries to avoid the un-necessary re-renders problem that the React Context
has by only re-rendering what is upmost needed. As a result performance can be boosted dramatically.
This is NOT a state management library. Just a performant React Context
replacement. You can also mix this up with redux for example and get a full redux experience but this is outside the scope of this library.
Libraries comparison
The bordered area is where the element is re-rendered. In the examples, the button is updating only one of the properties in the internal Context value.
| Using react-lightning-context
| Using React Context
|
| -------------------------------- | -------------------------------------- |
| | |
How to install
yarn add react-lightning-context
How to use it without Hooks
The main idea is following the same patterns and api that React Context
provides with a little twist.
const defaultValue = { valueA: { a: { b: 222, r: 333 } }, valueB: 222, valueC: 444 };
const Context = createLightningContext(defaultValue);
// `listenTo` can be (some examples):
// - valueA -> { a: { b: 222, r: 333 } }
// - valueA.a -> { b: 222, r: 333 }
// - valueA.a.b -> 222
const ExampleA = () => (
<Context.Provider>
<Context.Consumer listenTo={['valueC']}>
{({ valueC }) => <label>{valueC}</label> }
</Context.Consumer>
</Context.Provider>);
};
What is going on here?
createLightningContext
is creating the context.Context.Provider
is defining the area in which the context data is going to be shared.Context.Consumer
will listen to changes in the Context value and will re-rendered ONLY when the values on thelistenTo
prop in the context has changed. You can listen to more than one field, or you can go deep down into the props. ex:valueA.a.r
.
How to use it with Hooks
The main idea ia following the same patterns and api that React Context
provides with a little twist. This is doing the same as the previous example but with hooks.
const defaultValue = { valueA: { a: { b: 222, r: 333 } }, valueB: 222, valueC: 444 };
const Context = createLightningContext(defaultValue);
const UseLightningContextHookComponent = () => {
const { valueC } = useLightningContext({ listenTo: ['valueC'] }, Context);
return <label>{valueC}</label>;
};
// `listenTo` can be (some examples):
// - valueA -> { a: { b: 222, r: 333 } }
// - valueA.a -> { b: 222, r: 333 }
// - valueA.a.b -> 222
const ExampleA = () => (
<Context.Provider>
<UseLightningContextHookComponent />
</Context.Provider>);
};
What is going on here?
createLightningContext
is creating the context.Context.Provider
is defining the area in which the context data is going to be shared.useLightningContext
will listen to changes in the Context value and will be updated ONLY when the values on thelistenTo
prop in the context has changed. You can listen to more than one field, or you can go deep down into the props. ex:valueA.a.r
.
API Documentation
| Name | Supported ? | Description |
| ------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------- |
| React.createContext
renamed to createLightningContext
| Yes | It is how we create the context we use createLightningContext instead of React.createContext |
| Context.Provider
| Yes | |
| Class.contextType
| No | |
| Context.displayName
| Yes | |
| Context.Consumer
| Yes | A way of consuming a context value using components. |
| useContext
renamed to useLightningContext
| Yes | A way of consuming a context value using hook. Similar to useContext |
| Context.Mutator
| New | A component that provides a way of mutating the value of the context |
| useLightningContextMutator
| New | A Hook that provides a way of mutating the value of the context |
createLightningContext
It follows a similar api that the React.Context
provides. It only differs that we have a second parameter with configuration options.
| Parameters | | Types | Required | Values |
| ---------------- | -------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| First Parameter | defaultValue
| Any | Yes | The default value to initialize the Context |
| Second Parameter | Options
| Object | No | |
| | Options.waitBeforeUpdate
| Boolean | | Default: false. This helps when you have a very volatile Context value, that is constantly mutating. This helps by debouncing the updates so you can update the components less times having a similar effect with what concurrentMode
will have. |
It returns the Provider, Consumer, Mutator
components
Example
const Context = createLightningContext({ value: 'test' });
const Context = createLightningContext({ value: 'test' }, { waitBeforeUpdate: true });
Context.Provider
This does not have any props. Same as React.Context
it wraps the context experience.
Example
const Context = createLightningContext({ value: 'test' });
const TopLevelExperience = () => {
return <Context.Provider>// ... your experience</Context.Provider>;
};
Context.Consumer
This need to be nested inside a Provider
component. Same as React.Context
it uses the function render pattern and it execution a function when it need to be render.
| Properties | Type | Required | Description |
| ---------- | --------------- | -------- | -------------------------------------------------------------------------------- |
| listenTo
| Array< String > | Yes | Properties from the Context.value
that you want to listen to. It can be nested |
It returns a function that is executed passing a mapped object with the binding
Example
const Context = createLightningContext({ value: { first: 1, second: 2 } });
const TopLevelExperience = () => {
return <Context.Provider>
<Context.Consumer listenTo={['value.first', 'value.seconds']}>
{
(values) => //... anything to render
}
</Context.Consumer>
</Context.Provider>;
};
Return value example
if listenTo is ['value.first', 'value.seconds']
the render function that will execute is
({ 'value.first': 123, 'value.seconds': 333 }) => //...anything to render
useLightningContext
Same as Consumer
but as a Hook api (similar to the useContext
hook)
| Properties | Type | Required | Description |
| ---------- | ---------------------------------------- | -------- | -------------------------------------------------------------------------------- |
| listenTo
| Array | Yes | Properties from the Context.value
that you want to listen to. It can be nested |
| Context
| createLightningContext
returned object | Yes | The context you are using |
const result = useLightningContext({ listenTo: [...] }, Context);
Context.Mutator
This need to be nested inside a Provider
component. This is a component that provides a callback to update the internal context value. It uses the function render pattern and it execute a function when it need to be render passing the callback. No props are available.
It returns a function that is executed passing a callback function called setContextValue
. This will updates the internal values and ONLY re-render what has changed and has someone listening.
Example calling setContextValue
The value parameter is the updated context value
setContextValue((value) => {
return {
...value,
...yourChangeGoesHere,
};
});
Example
const Context = createLightningContext({ value: { first: 1, second: 2 } });
const TopLevelExperience = () => {
return <Context.Provider>
<Context.Mutator>
{
({ setContextValue }) => //... anything that want to use setContextValue
}
</Context.Mutator>
</Context.Provider>;
};
useLightningContextMutator
Same as Context.Mutator
but as a Hook.
| Properties | Type | Required | Description |
| ---------- | ---------------------------------------- | -------- | ------------------------- |
| Context
| createLightningContext
returned object | Yes | The context you are using |
Example
const setContextValue = useLightningContextMutator(Context);