Map injected React props from Higher Order Components to child components.
This is best used as an enhancement to the Redux Container Pattern.
yarn add map-props-to-children
# Or
npm install --save map-props-to-children
# ES6+
import mapPropsToChildren from "map-props-to-children";
# ES5
var mapPropsToChildren = require("map-props-to-children");
This library includes the following function:
mapPropsToChildren({ children, injectedProps, props })
Returns a list of the children components provided, but with new props injected into each child's props (shallow). The exported function has a fixed arity of 1 that accepts the following properties on the argument object:
children
: List of child components to clone and inject props into. Its existing props takes highest precedenceinjectedProps
: The props that will be injected into child components. It takes second-highest precedenceprops
: Props from the container component calling this function. Allows for the container to define some default prop values. It takes the lowest precedence
Suppose your project renders this dumb component:
export default function StockTicker({ stocks }) {
return (
<div>
<h2>Stock Ticker</h2>
{stocks.map((stock, index) => (
<p key={index}><b>{stock.name}:</b> {stock.price}</p>
)}
</div>
);
}
You will pass props to StockTicker
via a Redux container, but you don't want the container know anything about the component so that they are decoupled from each other. A theoretical app that uses this container would look like so:
export default function App() {
return (
<StockItemListContainer>
<StockTicker />
</StockItemListContainer>
);
}
The StockItemListContainer
knows nothing about the types of its children components, but can still inject props from the Redux state into them using mapPropsToChildren
:
function StockItemListContainer({ items, children, ...props }) {
const injectedProps = { items };
return (
<div>
{mapPropsToChildren({ children, injectedProps, props })}
</div>
);
}
function mapStateToProps(state) {
return {
items: state.items,
};
}
export default connect(mapStateToProps)(StockItemListContainer);
Now, you can easily reuse the same container for a different component that accepts the items
prop:
export default function Widget() {
return (
<StockItemListContainer>
<StockWidget />
</StockItemListContainer>
);
}
This project is licensed under the MIT License. See LICENSE for more details.
This project was made possible through contributions from the following people: