1- import _ from 'lodash'
1+ const handledPropsCache = { }
2+
3+ /**
4+ * Push all `source` array elements to the `target` array if they don't already exist in `target`.
5+ *
6+ * @param {Array } source - An array of elements to add to the `target`
7+ * @param {Array } target - An array to receive unique elements from the `source`
8+ * @returns {Array } Mutated `target` array
9+ */
10+ const pushUnique = ( source , target ) => source . forEach ( x => {
11+ if ( target . indexOf ( x ) === - 1 ) target . push ( x )
12+ } )
13+
214/**
315 * Returns an object consisting of props beyond the scope of the Component.
416 * Useful for getting and spreading unknown props from the user.
@@ -7,13 +19,27 @@ import _ from 'lodash'
719 * @returns {{} } A shallow copy of the prop object
820 */
921const getUnhandledProps = ( Component , props ) => {
10- const handledProps = _ . union (
11- Component . autoControlledProps ,
12- _ . keys ( Component . defaultProps ) ,
13- _ . keys ( Component . propTypes ) ,
14- )
22+ const { _meta : { name } , autoControlledProps, defaultProps, propTypes } = Component
23+
24+ let handledProps = handledPropsCache [ name ]
25+
26+ // ----------------------------------------
27+ // Calculate handledProps once and cache
28+ // ----------------------------------------
29+ if ( ! handledProps ) {
30+ handledProps = [ ]
31+
32+ if ( autoControlledProps ) pushUnique ( autoControlledProps , handledProps )
33+ if ( defaultProps ) pushUnique ( Object . keys ( defaultProps ) , handledProps )
34+ if ( propTypes ) pushUnique ( Object . keys ( propTypes ) , handledProps )
35+
36+ handledPropsCache [ name ] = handledProps
37+ }
1538
16- return _ . omit ( props , handledProps )
39+ return Object . keys ( props ) . reduce ( ( acc , prop ) => {
40+ if ( handledProps . indexOf ( prop ) === - 1 ) acc [ prop ] = props [ prop ]
41+ return acc
42+ } , { } )
1743}
1844
1945export default getUnhandledProps
0 commit comments