Reputation: 542
In my implementation I pass a reactelement (at least that's what I think) as a prop.
I would like to render this prop as it's own React Component but the browser complains that it is an object.
Code to clarify:
In parent:
render() {
return <SortableItem {...extraProps} item={React.cloneElement(item, extraProps)} />
}
The item
prop contains the element I want to render in SortableItem
In SortableItem render:
I want to do something like this:
render() {
return <props.item />
}
When I log props.item
I get this:
Object {$$typeof: Symbol(react.element), key: "item-5", ref: null, props:
Object, type: function…}
$$typeof:Symbol(react.element)
key:"item-5"
props:Object
ref:null
type:function _class()
I am confused as to why $$typeof
would say this is a react element indeed, but type says it's a function _class()
and when I log/render the browser says it's an object.
This is the error I get in the browser when rendering <props.item />
in SortableItem
Fatal Exception:Uncaught Invariant Violation: Element type is invalid:
expected a string (for built-in components) or a class/function (for
composite components) but got: object. Check the render method of
`SortableItem`.(reload cancelled)
Upvotes: 11
Views: 31569
Reputation: 885
The answer to this is that every block of logic you manipulate in the virtual DOM needs to be wrapped in a single container element. You can insert and remove a list of components, but they need to be wrapped in a single element. If you return
return (
<div>
<SortableItem {...extraProps} item={React.cloneElement(item, extraProps)} />
</div>
)
you'll be ok. Vue and Angular have built in template elements for this purpose. I normally make some sort of template component for this purpose in React that is just a div with no margin or padding that can be used to wrap lists of elements.
Upvotes: 1
Reputation: 942
Try this,
Approach 1
In parent:
render() {
return <SortableItem {...extraProps} item={<YourComponent />} />
}
In SortableItem render:
render() {
return {this.props.item}
}
Approach 2: In parent:
render() {
return <SortableItem {...extraProps} >
<YourComponent />
</SortableItem>
}
In SortableItem render:
render() {
return {this.props.children}
}
Upvotes: 4