UNPKG

1.35 kBJavaScriptView Raw
1import React from 'react';
2
3// memoization cache
4const cache = new Map();
5
6export const filterProps = (props = {}, blacklist = []) =>
7 Object.entries(props).reduce((r, [k, v]) => {
8 if (!blacklist.includes(k)) {
9 r[k] = v;
10 }
11 return r;
12 }, {});
13
14const fromRenderProp = (elementType, customProps = []) => {
15 const isComposite = typeof elementType === 'function';
16
17 // if `elementType` is a function, it's already a component
18 if (isComposite) {
19 return elementType;
20 }
21
22 // sort and de-dupe `customProps`
23 const uniqueCustomProps = Array.from(new Set([...customProps].sort()));
24
25 // hash arguments for memoization
26 const key = `${elementType}//${uniqueCustomProps.join(',')}`;
27
28 // only create a new component if not cached
29 // otherwise React will unmount on every render
30 if (!cache.has(key)) {
31 // create an SFC that renders a node of type `elementType`
32 // and filter any props that shouldn't be written to the DOM
33 const Component = props =>
34 React.createElement(
35 elementType,
36 filterProps(props, uniqueCustomProps)
37 );
38
39 Component.displayName = `fromRenderProp(${elementType})`;
40 cache.set(key, Component);
41 }
42
43 return cache.get(key);
44};
45
46export default fromRenderProp;