How can I confirm that a react element received through props (like children
for example) is of a given type in my render method?
Say I have a List
element and a ListItem
element. In the render method of List
, I want to look for all of the children that were passed and do something special with any children that are ListItem
s.
I did find an implementation that works, but only after trial and error. See the code below. (React 15.4.2)
List.jsx
import ListItem from 'list-item';
...
React.Children.map(children, child => {
console.log(child); // function ListItem() { ... }
console.log(ListItem); // function ListItem() { ... }
if (isListItem(child)) {
return (...);
}
return child;
})
// this implementation does not work
isListItem(element) {
return (element.type === ListItem);
}
// this implementation does work, but might break if I'm using something like uglify or if I use `react-redux` and `connect()` ListItem (as that will change the display name)
isListItem(element) {
return (element.type.displayName === 'ListItem');
}
// this implementation does work
isListItem(element) {
return (element.type === (<ListItem />).type);
}
ListItem.jsx
class ListItem expends React.component {
...
}
export default ListItem;
So, the last implementation seems to work, but why doesn't the first implementation work? I can't find any material relating to this in the react documentation, though I did find some stack overflow questions about the same thing. The answers provided in those questions, however, indicate that the first implementation should work (though they are for older versions of React)
only allow children of a specific type in a react component
Comparing two components - is Component X an instance of Component A
Generally, the type you should first try when adding a type for the children of your React component is React. Node . Note: You need to use import * as React from 'react' here instead of import React from 'react' to get access to the React.
Children is a special prop that allows us to pass in any type of element. It could be a number, a string, a boolean, an array of elements or even another component.
children is a special prop, automatically passed to every component, that can be used to render the content included between the opening and closing tags when invoking a component. These kinds of components are identified by the official documentation as “boxes”.
While this question is old, I ran into this problem while using react-hot-loader
and took me a while to finally find this GitHub issue explaining why it behaved this way.
This is intended, react-hot-loader@3 patches
React.createElement(<ImportedComponent />)
is equivalent toReact.createElement(ImportedComponent)
so that it returns an element of a proxy wrapper for your components instead of the original component, this is part of allows to replace methods on the component without unmounting.- @nfcampos
In addition to the methods you discovered, RHL now provides a areComponentsEqual()
function with a dedicated section in their README.
import { areComponentsEqual } from 'react-hot-loader'
const element = <Component />
areComponentsEqual(element.type, Component) // true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With