I have a prop onNotifyChange
which is a function and I call it in the onChange
of an input.
And it has a PropType for func
.
MyComponent.propTypes = {
onNotifyChange: PropTypes.func,
}
When calling onNotifyChange
, do I need to check typeof
const onChange = e => {
// do some stuff
if(onNotifyChange && typeof onNotifyChange === 'function'){
onNotifyChange()
}
}
or just checking if it's falsy?
const onChange = e => {
// do some stuff
if(onNotifyChange){
onNotifyChange()
}
}
Does PropTypes.bar
removes the need for checking typeof foo === 'bar'
?
Yes you need to check the types of your props even when using prop-types
. The prop-types
library gives you runtime warnings in the development mode of React.
In the example below we are using the development build of React. We have a component H1
with required function prop. Notice when using the H1
component within App
, without passing a value for the className
prop, an error is thrown, and prop-types
has logged a warning.
So, you cannot rely on prop-types
to prevent bad props being passed down to children.
function H1({ className, children }) {
// this will throw if className is not a function
return <h1 className={className()}>{children}</h1>
}
H1.propTypes = {
className: PropTypes.func.required
}
function App() {
return <H1>Test</H1>
}
ReactDOM.render(<App />, document.querySelector("#root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.development.js"></script>
<div id=root></div>
To prevent this kind of thing happening at runtime you can:
Even better, you can do both, as in the example below:
function H1({ className, children }) {
/* do some validation of your props
(throwing here to demonstrate that the default prop set below
works - I do not recommend throwing errors within components
like this unless you know what you're doing, e.g. have an error
boundary to catch behaviour like this) */
if (typeof className !== "function") {
throw new Error("expecting className prop to be function")
}
return <h1 className={className()}>{children}</h1>
}
H1.propTypes = {
className: PropTypes.func.required
}
H1.defaultProps = {
className: () => ""
}
function App() {
return <H1>Test</H1>
}
ReactDOM.render(<App />, document.querySelector("#root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.development.js"></script>
<div id=root></div>
This way your application will not crash due to a bad prop value, and in development mode you will see the warning logged by prop-types
.