Reputation: 6546
Following the new context API for react 16.3.0 I've created HOC so that my context is easier consumed by many components.
But if I have more then one component that consumes context nested one after another, react throws error.
Lets say for my example i have css module i want to pass down and HOC looks as follow:
import React from 'react';
import CssModuleContext from './CssModuleContext';
export default function withCssModule(Component) {
return function CssModuleComponent(props) {
return (
<CssModuleContext.Consumer>
{cx => <Component {...props} cssModule={cx} />}
</CssModuleContext.Consumer>
);
};
}
Then I have two components that consumes this context:
@withCssModule
export default class A extends PureComponent {
static B = B;
static propTypes = {
cssModule: PropTypes.func,
};
render() { ... }
}
@withCssModule
export default class B extends PureComponent {
static propTypes = {
cssModule: PropTypes.func,
};
render() { ... }
}
And the usage looks as follow:
render() {
return(
<A>
<A.B />
</A>
);
}
React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
which throws an error, when I use only one of those components there is no error, but i can not nest them. Is this a common error? Is there a fix for it ? Or maybe am I doing something wrong ?
CssModuleContext.js
import React from 'react';
const defaultCssModule = null; // we want to use component defined module by default
const CssModuleContext = React.createContext(defaultCssModule);
export default CssModuleContext;
CssModuleProvider.js
import React from 'react';
import PropTypes from 'prop-types';
import CssModuleContext from './CssModuleContext';
export default class CssModuleProvider extends React.Component {
static propTypes = {
children: PropTypes.element.isRequired,
cssModule: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
const { cssModule } = this.props;
this.state = { cssModule };
}
render() {
return (
<CssModuleContext.Provider value={this.state.cssModule}>
{React.Children.only(this.props.children)}
</CssModuleContext.Provider>
);
}
}
Upvotes: 3
Views: 2290
Reputation: 6546
The problem was because i was exporting HOC the static variables where not accessible on that object.
doing the following
@withCssModule
export default class A extends PureComponent {
static B = B;
static propTypes = {
cssModule: PropTypes.func,
};
render() { ... }
}
and then trying access the B like that <A.B />
will not work because we export the wrapper not the class itself.
Upvotes: 2