Consider the following scenario:
import React, { Component } from 'react';
import LocaleService from '../Services/LocaleService.js';
const defaultStore = {
loaded: false,
locales: []
};
const LocalesContext = React.createContext(defaultStore);
class LocalesProvider extends Component
{
state = defaultStore;
load() {
const service = new LocaleService(), that = this;
service.fetch().then(function (locales) {
that.setState({ locales: locales, loaded: true });
});
}
data() {
return this.state;
}
componentDidMount() {
this.load();
}
render() {
return (
<LocalesContext.Provider value={this.data()}>
{this.props.children}
</LocalesContext.Provider>
);
}
}
export default LocalesProvider;
import React, { Component } from 'react';
import Sidebar from './Sidebar.js';
import Topbar from './Topbar.js';
import Content from './Content.js';
import LocalesProvider from './Providers/LocalesProvider.js';
class App extends Component
{
state = {
ready: true
}
render() {
if (this.state.ready) {
return (
<div>
<Topbar/>
<section className="section">
<section className="columns" style={{height: '100vh'}}>
<div>
<LocalesProvider.Consumer>
{ data =>
(
<Sidebar isReady={data.loaded} locales={data.locales}/>
)
}
</LocalesProvider.Consumer>
</div>
<main className="column" style={{overflow: 'auto', position: 'relative'}}>
<Content/>
</main>
</section>
</section>
</div>
);
} else {
return ('Loading...');
}
}
}
export default App;
import React, { Component } from 'react';
import LocalesProvider from './Providers/LocalesProvider.js';
import { NavLink, HashRouter } from "react-router-dom";
class Sidebar extends Component
{
constructor(props) {
super(props);
}
buildLocaleLinks (locales, uri) {
if (!this.props.isReady) {
return 'Loading...';
}
if (!locales.length) {
return null;
}
return locales.map(function (locale) {
return (
<li key={'navigation.translate.' + locale.props.key}>
<NavLink replace to={'/' + uri + '/' + locale.props.key}>
{locale.props.key}
</NavLink>
</li>
);
})
}
render () {
return (
<HashRouter>
<aside className="menu">
<p className="menu-label">
Menu
</p>
<ul className="menu-list">
<li>Translate</li>
<li>
<ul>
<LocalesProvider.Consumer>
{locales => (
this.buildLocaleLinks(locales, 'translate')
)}
</LocalesProvider.Consumer>
</ul>
</li>
<li>Validate</li>
<li>
<ul>
<LocalesProvider.Consumer>
{locales => (
this.buildLocaleLinks(locales, 'validate')
)}
</LocalesProvider.Consumer>
</ul>
</li>
</ul>
</aside>
</HashRouter>
);
}
}
export default Sidebar;
Element 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.
componentWillChangeProps
to the underlying children upon state update? – Okeefe