Reputation: 10916
I have this piece of code:
const defaultValue = new Api()
const ApiContext = React.createContext(defaultValue);
const ApiProvider = ApiContext.Provider;
const ApiConsumer = ApiContext.Consumer;
const withApi = (Enhanced: any) => {
return (
<ApiConsumer>
{api => {
return <Enhanced api={api}/>;
}}
</ApiConsumer>
)
}
export default ApiContext;
export {ApiContext, ApiProvider, ApiConsumer, withApi};
And in my app, I have something like this:
const api = new ApiManager({...});
ReactDOM.hydrate(
<Provider store={store}>
<BrowserRouter>
<ApiProvider value={api}>
<Main />
</ApiProvider>
</BrowserRouter>
</Provider>, document.querySelector('#app')
);
But this line return <Enhanced api={api}/>;
causes these errors:
1.
Warning: React.createElement: 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?
2.
Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
3.
Uncaught (in promise) 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 `Context.Consumer`.
What I'm I doing wrong here? How can I pass the api prop to an enhanced component?
[EDIT]
This is how I'm calling my component:
App.tsx
class App extends React.Component {
render() {
return (
<React.Fragment>
<Switch>
{routes.map(({ path, exact, component: C }) => {
return <Route
key={path}
path={path}
exact={exact}
render={(props) => {
return withApi(<C {...props} />);
}} />
})}
</Switch>
</React.Fragment>
)
}
}
Upvotes: 3
Views: 1008
Reputation: 281646
You haven't written your withApi HOC correctly. It should return a functional component instead of JSX
const withApi = (Enhanced: any) => {
return (props) => {
return (
<ApiConsumer>
{api => {
return <Enhanced {...props} api={api}/>;
}}
</ApiConsumer>
)
}
}
and use it like
class App extends React.Component {
render() {
return (
<React.Fragment>
<Switch>
{routes.map(({ path, exact, component: C }) => {
const Comp = withApi(C);
return <Route
key={path}
path={path}
exact={exact}
render={(props) => {
return <Comp {...props}/>
}} />
})}
</Switch>
</React.Fragment>
)
}
}
Upvotes: 1