At times one may be justified in the argument that cognitive (over)load is just an expected part of the overall developer experience. Fortunately, there are numerous steps we can take to minimize the general noise which tends to distract our intended focus. One particularly simple – yet effective – example is to remove unnecessary redundancy wherever possible. In doing so, we afford both our peers and ourselves a codebase which, over time, becomes considerably easier to maintain.
For instance, when performing code reviews, more often than not I tend to see considerable redundancy when specifying React PropTypes. Typically, something along the lines of:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import React from 'react'; import PropTypes from 'prop-types'; /* import React, {PropTypes} from 'react'; // react < v.15.5 */ ... LoginForm.propTypes = { validate : PropTypes.func.isRequired, authenticate : PropTypes.func.isRequired, persistCredentials : PropTypes.func.isRequired, fetching : PropTypes.bool.isRequired, rememberMe : PropTypes.bool.isRequired, username : PropTypes.string, password : PropTypes.string, muiTheme : PropTypes.object, errors : PropTypes.object } ... |
As can be seen, with each new prop we are redundantly referencing React PropType lookup paths. And, while the ideal components will have a limited number of props (either connected directly, or passed down), the redundancy still remains for any component which references the same prop type. Considering the number of components a given application may contain, we can rightfully assume that the above redundancy will grow proportionally.
With the above in mind, we can easily reduce the redundancy (as well as micro-optimize the lookup paths) be simply destructuring the props of interest as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ... const {func, object, string, bool} = PropTypes; LoginForm.propTypes = { validate : func.isRequired, authenticate : func.isRequired, persistCredentials : func.isRequired, fetching : bool.isRequired, rememberMe : bool.isRequired, username : string, password : string, muiTheme : object, errors : object } ... |
While I would consider the above to be simplified enough; one could also take this a step further and destructure the isRequired
props, which, in some circumstances, may be useful as well:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ... const { func: {isRequired:funcReq}, bool: {isRequired:boolReq}, object, string } = PropTypes; LoginForm.propTypes = { validate : funcReq, authenticate : funcReq, persistCredentials : funcReq, fetching : boolReq, rememberMe : boolReq, username : string, password : string, muiTheme : object, errors : object } ... |
Admittedly, this example is rather straight-forward; however, it does help to emphasize the point that only through consistent vigilance can we ensure our source will continue to evolve organically while remaining as simple as possible.
Great tip! Thanks for sharing!