Skip to content

Commit 1036fb1

Browse files
authored
perf(getUnhandledProps): replace lodash with vanilla js (#860)
perf(getUnhandledProps): replace lodash with vanilla js
1 parent cf14691 commit 1036fb1

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/lib/getUnhandledProps.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
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
*/
921
const 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

1945
export default getUnhandledProps

test/specs/lib/getUnhandledProps-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getUnhandledProps } from 'src/lib'
88
function TestComponent(props) {
99
return <div {...getUnhandledProps(TestComponent, props)} />
1010
}
11+
TestComponent._meta = { name: 'TestComponent' }
1112

1213
beforeEach(() => {
1314
delete TestComponent.propTypes

0 commit comments

Comments
 (0)