Disclaimer: I've seen react-router is not rendering anything and You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports but the solutions in there did not work for my case.
I am trying to render two component in a Switch in App.js like this
render() {
let MyHome = (props) => {
return(
<Home {...props} toggleFilter={this.state.filterDrawerOpen}/>
)
}
console.log("Mue")
let backdrop;
if (this.state.sideDrawerOpen) {
backdrop = <Backdrop click={this.backdropClickHandler} />
}
return (
<div className="container-fluid">
<div className="row">
<Toolbar
filterClickHandler = {this.filterToggleClickHandler}
path = {this.props.location.pathname}
signOut = {this.signOut}
drawerClickHandler={this.drawerToggleClickHandler} />
<SideDrawer click = {this.drawerToggleClickHandler} signOut = {this.signOut} show={this.state.sideDrawerOpen} />
{backdrop}
</div>
<main style={{marginTop: '1px'}}>
<div className="App">
<Switch>
<Route exact path ='/' render = {MyHome}/>
<Route path='/profile' component = {Profile}/>
</Switch>
</div>
</main>
</div>
);
export default withAuthenticator(App, false);
}
}
The problem is that the Route with the MyHome component throws this error: console logs with error and debug code from Home render.
The Home component is huge so I`ll include just the relevant code here
import React, { Component } from 'react';
import Auth from '@aws-amplify/auth';
import { API } from 'aws-amplify';
import ProfileRedirect from "./components/ProfileRedirect";
import LoadingAnimation from './components/LoadingAnimation';
import ReadingSpeed from "./components/ReadingSpeed";
import './Tags.css';
import Articles from "./components/Articles";
import { CSSTransitionGroup } from 'react-transition-group'
import FilterArea from './components/FilterArea';
import "react-datepicker/dist/react-datepicker.css";
import FilterDrop from './components/FilterDrop';
import FilterDrawer from './components/FilterDrawer';
import { withRouter } from "react-router";
let apiName = 'userApi';
let path = '/users/';
class Home extends Component {
constructor(props){
super(props);
this.state = {
isLoading: true,
firstLogIn: true,
filterDrawerOpen:false,
user :{
phone:"",
readingSpeed:0,
email:"",
username:"",
articles: [],
interests: [],
saved:[],
filters:{
minutes:null,
authors:[],
sources:[],
minDate:{},
selectedInterests:[],
selectedDate:{}
}
}
}
this.dateFilter = this.dateFilter.bind(this)
}
async componentDidMount(){
let userEntry;
let date = new Date();
date.setMonth(date.getMonth()-1)
// const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const loggedUser = await Auth.currentAuthenticatedUser();
userEntry = await API.get(apiName,path + loggedUser.username);
if(userEntry.hasOwnProperty("userName")){
let uniqueResults;
let results = await this.callDatabase(userEntry)
uniqueResults = results.reduce(function (p, c) {
if (!p.some(function (el) {return (el.title === c.title && el.author === c.author);}))
p.push(c);
return p;
}, []);
this.setState({
isLoading:false,
firstLogIn:false,
filterDrawerOpen:false,
user : {
phone:userEntry.userName,
readingSpeed:userEntry.readingSpeed,
email:userEntry.userEmail,
username:userEntry.userName,
articles: uniqueResults,
interests:userEntry.userInterests,
saved: userEntry.savedArticles,
filters:{
minutes:null,
authors:[],
sources:[],
minDate:date,
selectedDate:{},
selectedInterests:[]
}
}
})
}else {
this.setState({
isLoading:false
})
}
}
async callDatabase (userEntry,sources,freeMode){...}
authorFilter = selected => {...}
sourceFilter = selected => {...}
interestFilter = selected => {...}
minutesFilter(value) {...}
componentWillReceiveProps(newProps) {
if(newProps.toggleFilter !== this.props.toggleFilter){
this.filterToggleClickHandler();
}
}
filterToggleClickHandler = () => {...}
filterDropClickHandler = () => {...}
dateFilter(selected) {...}
generateOptions = filter => {...}
async updateDataBase(readingSpeed){...}
render() {
let filterdrop;
if(this.state.filterDrawerOpen) {
filterdrop = <FilterDrop click = {this.filterDropClickHandler}/>
}
console.log(this.state)
const stillLoading = () => {
return (
<div className="loading">
<LoadingAnimation
type = {"spinningBubbles"}
color = {"aqua"}
/>
</div>);
}
const articles = (filterA, filterS, filterI, filterM) => {
let articles = this.state.user.articles;
let newDate = this.state.user.filters.selectedDate;
let readingTime = this.state.user.readingSpeed;
let check;
if(newDate === null){
check = true
}else {
check= Object.entries(newDate).length === 0 && newDate.constructor === Object
}
if(!check){
articles = this.checkDate(newDate,articles)
}
if(filterA.length){
articles = this.checkAuthors(filterA,articles)
}
if(filterS.length){
articles = this.checkSource(filterS,articles)
}
if(filterI.length){
articles = this.checkInterest(filterI,articles)
}
if(!(filterM === null) && filterM!==0){
articles = this.checkMinutes(filterM,readingTime,articles)
}
return(
<div className="wrapper">
{
articles.map(function(article) {
return (
<Articles
article = {article}
key = {article.id}
/>
)
})}
</div> );
}
if(this.state.isLoading){
return (
stillLoading()
);
}else if(!this.state.firstLogIn && this.state.user.articles.length>0 && this.state.user.readingSpeed >0){
console.log("Not loading, display articles")
return (
<CSSTransitionGroup
transitionName="example"
transitionAppear={true}
transitionAppearTimeout={1000}
transitionEnter={false}
transitionLeave={false}>
{this.filtersArea()}
{filterdrop}
{articles(this.state.user.filters.authors,this.state.user.filters.sources,
this.state.user.filters.selectedInterests,this.state.user.filters.minutes)}
</CSSTransitionGroup>
);
}else if(this.state.firstLogIn || this.state.user.readingSpeed === 0){
return(
<ReadingSpeed updateDb = {this.updateDataBase.bind(this)}/>
);
}
else if(this.state.user.interests.length === 0){
return(
<div>
<ProfileRedirect/>
</div>
);
}else return null;
}
}
export default Home;
The debug code in console.log("Not loading, display articles")
in the Home component render is displayed in the console as can be seen here
but the component does not render.
Here is the full code for App.js
import React, { Component } from 'react';
import { library } from '@fortawesome/fontawesome-svg-core'
import './App.css';
import awsmobile from './aws-exports';
import { withAuthenticator } from 'aws-amplify-react';
import {Route, Switch, Link} from 'react-router-dom';
import Auth from '@aws-amplify/auth';
import Profile from './Profile';
import Home from './Home';
import Amplify, { API } from 'aws-amplify';
import Toolbar from './components/Toolbar';
import SideDrawer from './components/SideDrawer';
import Backdrop from './components/Backdrop';
import {faCheck} from "@fortawesome/free-solid-svg-icons/faCheck";
import {faSave} from "@fortawesome/free-solid-svg-icons/faSave";
import {faTrashAlt} from "@fortawesome/free-solid-svg-icons/faTrashAlt";
import {faExternalLinkAlt} from "@fortawesome/free-solid-svg-icons/faExternalLinkAlt";
import {faSignOutAlt} from "@fortawesome/free-solid-svg-icons/faSignOutAlt";
import {faUserCircle} from "@fortawesome/free-solid-svg-icons/faUserCircle";
import {faHome} from "@fortawesome/free-solid-svg-icons/faHome";
import {faSort} from "@fortawesome/free-solid-svg-icons/faSort";
library.add(faCheck)
library.add(faSave)
library.add(faTrashAlt)
library.add(faExternalLinkAlt)
library.add(faSignOutAlt)
library.add(faUserCircle)
library.add(faHome)
library.add(faSort)
//TODO
// Add Bloomberg API, The Sun, Mail online
// Make the nav bar come back when scroll wheel up
// Add change password and email adress in profile -check for mobile friendlyness
let apiName = 'userApi';
let path = '/users/';
Amplify.configure(awsmobile);
class App extends Component {
constructor(props){
super(props);
this.state = {
sideDrawerOpen:false,
filterDrawerOpen:false,
user:{}
};
}
drawerToggleClickHandler = () => {
this.setState((prevState) => {
return {
sideDrawerOpen: !prevState.sideDrawerOpen,
filterDrawerOpen:false,
};
});
};
filterToggleClickHandler = () => {
this.setState((prevState) => {
return {filterDrawerOpen: !prevState.filterDrawerOpen,
sideDrawerOpen: false};
})
}
backdropClickHandler = () => {
this.setState({sideDrawerOpen: false});
};
signOut = () => {
Auth.signOut().then(() => {
this.props.onStateChange('SignedOut');
});
}
render() {
let MyHome = (props) => {
return(
<Home {...props} toggleFilter={this.state.filterDrawerOpen}/>
)
}
console.log("Mue")
let backdrop;
if (this.state.sideDrawerOpen) {
backdrop = <Backdrop click={this.backdropClickHandler} />
}
return (
<div className="container-fluid">
<div className="row">
<Toolbar
filterClickHandler = {this.filterToggleClickHandler}
path = {this.props.location.pathname}
signOut = {this.signOut}
drawerClickHandler={this.drawerToggleClickHandler} />
<SideDrawer click = {this.drawerToggleClickHandler} signOut = {this.signOut} show={this.state.sideDrawerOpen} />
{backdrop}
</div>
<main style={{marginTop: '1px'}}>
<div className="App">
<Switch>
<Route exact path ='/' render = {MyHome}/>
<Route path='/profile' component = {Profile}/>
</Switch>
</div>
</main>
</div>
);
}
}
export default withAuthenticator(App, false);
And index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.css';
import {BrowserRouter as Router, Route} from 'react-router-dom';
ReactDOM.render(
<Router>
<Route path='/' render={(props )=> <App {...props}/>}/>
</Router>,
document.getElementById('root'));
serviceWorker.unregister();
What am I missing?