
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
react-composition-provider
Advanced tools
A High Order Component library for components to follow the Composition Provider pattern
react-composition-provider is a small react library that helps you implement a Composition Provider pattern.
The Composition Provider pattern tries to make prop drilling more ergonomic.
npm i --save react-composition-provider
Let's look at a simple example of Menu, Card, CardList, NewsList & WeatherList components.
Where CardList contains Card and Card contains Menu.
Where NewsList & WeatherList both contain CardList.
We want to pass props from NewsList & WeatherList to Menu, this is how you do it:
// Menu.js
import { withCompositionProvider } from 'react-composition-provider';
const InnerMenu = ({ cardId, items }) => {
// This is where the actual menu code would be.
};
export default withCompositionProvider(InnerMenu);
// Card.js
import Menu from './Menu';
export default (props) => {
return (
<div>
<Menu cardId={props.id}/>
</dib>
)
}
And in NewsList & WeatherList you'd do this:
// NewsList.js
import Menu from 'Menu';
export default (props) => {
const actions = [{ text: 'remove' }, { text: 'star' }];
return (
<Menu.Provider items={actions} >
<CardList cards={props.news}/>
</Menu.Provider>
)
}
// WeatherList.js
import Menu from 'Menu';
export default (props) => {
const actions = [{ text: 'remove location' }];
return (
<Menu.Provider items={actions} >
<CardList cards={props.locations}/>
</Menu.Provider>
)
}
And that's it!
Now every time you want to supply extra props to a decendant Menu component just render Menu.Provider with what you need!
This is the basic usage but the library gives you a lot more features than just this, like:
Menu.Provider in the same tree, that way even if someone is using Menu.Provider in a component you can't change you'll still be able to pass more props to it!Menu.Provider can add props you can use Menu.Provider.Scoped.<Menu.Provider ref={...} and get the ref of the provider, right?ref, style, className and children) and gives you a way to define the composition for each prop.kids because obviously the children prop is already taken.Menu was rendered somewhere, it doesn't mean that InnerMenu has to be mounted.Menu.Provider and which aren't.Most of these can be configured through a second options argument to withCompositionProvider:
import { withCompositionProvider, composers } from 'react-composition-provider';
export default withCompositionProvider(MyComponent, {
// Object defining all the polyfills used by this package.
polyfills: {
// If you're using an old version of react that doesn't have React.createContext,
// you'll need to supply a polyfill for it, something like - https://github.com/jamiebuilds/create-react-context
createContext: React.createContext
}
// Allows you to control when the inner component actually mounts.
// Returns true if the component should mount and false when it shouldn't.
// props - all the composed props for this component
// propsChain - an array of props, ordered by closeness to the actual component.
// where propsChain[0] is given directly to the component and propsChain[1] is the closest Provider, and so on.
mountWhen: ({ props, propsChain }) => true,
// An array of props to ignore from all the Providers up the chain.
ignore: [],
// The most advanced configuration.
// Gives you full control over the composition of each and every prop.
// Each key in this object is the prop name and the value is a function that composes it and returns said composition.
// Luckily, you don't have to think about it too much because react-composition-provider comes with a built-in set of composers.
// To use these composers just import it like this:
// import { composers } from 'react-composition-providers';
//
// There are 2 available variations for some of the composers, reverse or take.
// reverse - composes the same way but just in reverse order.
// take - an object with first, last & index that takes a single element from the array.
// Note that all of the composers implement the take capabiliy, the ones marked with reverse can also use that capability.
//
// These are the available composers:
// 1. composers.node() - combines an array of nodes as siblings using React.Fragment. (reverse)
// 2. composers.string(separator: String) - combines an array of strings with the given separator (defaults to " " - space). (reverse)
// 3. composers.object(merge: (objects: Array<Object>) => Object) - combines an array of objects by merging them together.
// the first one is the least specific and the last is the most specific.
// the merge callback takes in an array of objects and returns a merged object (defaults to Object.assign). (reverse)
// 4. composers.array() - combines an array of arrays to a single array (essentially a flatMap). (reverse)
// 5. composers.func.result.compose(composer: Composer) - executes each function in the array sequentially, the composer parameter is used to combine the results.
// 6. composers.func.result.ignore() - executes each function in the array sequentially and ignores the result.
// 7. composers.bool.and() - combines an array of booleans to a single boolean value by "&&" all of them together.
// 8. composers.bool.or() - combines an array of booleans to a single boolean value by "||" all of them together.
// 9. composers.number.sum() - gets the sum of the array of numbers.
// 10. composers.number.min() - gets the minimum number of the array of numbers.
// 11. composers.number.max() - gets the maximum number of the array of numbers
// 12. composers.number.average() - gets the average of the array of numbers.
// 13. composers.date.min() - gets the minimum date of the array of dates.
// 14. composers.date.max() - gets the maximum date of the array of dates.
compose: {},
});
As you can see this API is very flexible, but tries to have sane defaults.
Prop drilling makes our components too specific, and tie the API of a component with the components it's composing (its implementation).
When these components change it will probably mean that the API will change too.
This applies to all the levels you "drill" the props, if something way down the line changes - all of them change.
What happens when you forget to drill some props? that's a tedious job of going through all the levels between where you have the prop value all the way down to the where it actually needs to be.
You might say that you can solve all of that with a state management library like redux - that's true.
You'd then need to define reducers, actions, and connect components to a store - just to pass some props down the line. It's like using a hammer for screws.
That's why react-composition-provider exists.
It creates a "portal" between the component itself and all the places you defined props for it.
It's very small (6kb non-gzipped) so you won't feel it, plus it'll probably help you save some boilerplate code so you code end up with a smaller bundle!.
Although this pattern can be very helpful and you're maybe thinking to yourself "I'm going to define all of my components like this now!".
JUST DON'T
General rules of thumb (there are probably more since this is new) of dos and don'ts with this pattern:
xxxProps - you already want to expose the props for xxx as part of your API.So, as with all patterns out there - make sure you understand what you're doing and don't abuse it.
MIT
FAQs
A High Order Component library for components to follow the Composition Provider pattern
The npm package react-composition-provider receives a total of 0 weekly downloads. As such, react-composition-provider popularity was classified as not popular.
We found that react-composition-provider demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.