1

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

debug code

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?

Octavian
  • 623
  • 2
  • 6
  • 17
  • I know it would be lacking props but, if you did this: `` instead of using `MyHome`, would it work? – go_diego Apr 10 '19 at 15:35

1 Answers1

0

The render props in react-router is supposed to be a function : Render props

Use either of the two following lines to fix your code:

<Route exact path ='/' render={() => <MyHome/>}/>

<Route exact path ='/' component={<MyHome}/>

Gaël S
  • 1,598
  • 6
  • 15
  • I've tried both in the past and none of them worked – Octavian Apr 10 '19 at 16:33
  • I've been trying to fix this for a couple of hours now and nothing seems to work – Octavian Apr 10 '19 at 16:35
  • The component is really huge. Try to comment everything in the render function, see if it works. If yes, start uncommenting line by line to find out where it breaks. – Gaël S Apr 10 '19 at 17:02
  • I've done that as well, I think there is a problem with the webpack. Anyway, thanks for advice. – Octavian Apr 10 '19 at 18:08
  • `this.filtersArea` is not declared anywhere in your code. Might be the issue – Gaël S Apr 11 '19 at 10:23
  • Well, if you are still having the issue, try to set up a codesandbox, that would be great to help you out – Gaël S Apr 11 '19 at 15:46
  • I've managed to fix the issues by going back to the previous version and adding functionality one function after another. That fixed it but I still don`t know what the issue was, I suspect it had something to do with the location of the Home component being changed in the webpack. Thanks for guidance :) – Octavian Apr 11 '19 at 16:37