I am working on increasing my knowledge of Higher Order Components. I am wondering if it is possible to render a "component," which is passed in as a prop to a higher order component "SuperCommentList." To my knowledge there is no way to render a component as "this.props.component" or even as an instance variable "this.WrappedComponent." I know this does not follow traditional HOC conventions, but was trying to determine if this was possible. I am receiving the errors below. Can anyone advise how I can achieve this?
Warning:
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: . Did you accidentally export a JSX literal instead of a component? at App
Error:
react-dom.development.js:28439 Uncaught Error: 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
App
. at createFiberFromTypeAndProps (react-dom.development.js:28439:1) at createFiberFromElement (react-dom.development.js:28465:1) at reconcileSingleElement (react-dom.development.js:15750:1) at reconcileChildFibers (react-dom.development.js:15808:1) at reconcileChildren (react-dom.development.js:19167:1) at updateContextProvider (react-dom.development.js:21154:1) at beginWork (react-dom.development.js:21649:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) at invokeGuardedCallback (react-dom.development.js:4277:1)
HOC Call
import CommentList from "./CommentList";
import data from "../utils/data";
import modelClass from "../utils/Model";
import SuperCommentList from "../utils/SuperCommentList";
const CommentListWithSubscription = withSubscription(CommentList, model.data);
function withSubscription(WrappedComponent, selectedData) {
const color = { color: selectedData.color };
return <SuperCommentList selectedData={selectedData} component={WrappedComponent} color={color}/>;
}
HOC Example below:
import React, {Component} from "react";
class SuperCommentList extends Component {
WrappedComponent;
constructor(props) {
super(props);
console.log("WithSubscription props:", props);
this.handleChange = this.handleChange.bind(this);
this.WrappedComponent = this.props.component;
this.state = {
data: this.props.selectedData,
};
}
componentDidMount() {
// ... that takes care of the subscription...
this.handleChange();
}
handleChange() {
this.setState({
data: this.props.selectedData,
});
}
render() {
console.log("WithSubscription State Data:", this.state.data);
return <this.WrappedComponent data={this.state.data} {...this.props.color}/>;
}
}
export default SuperCommentList;
CodePudding user response:
the HOC need to return a component, not a rendered DOM node.
So change the HOC to
function withSubscription(WrappedComponent, selectedData) {
const color = { color: selectedData.color };
return function ComponentWithSubscription() {
return <SuperCommentList selectedData={selectedData} component={WrappedComponent} color={color} />;
}
}