即使组件正在渲染,React route也不会加载组件

时间:2019-04-10 14:29:10

标签: javascript reactjs react-router rendering react-router-dom

免责声明:我见过react-router is not rendering anythingYou likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports,但那里的解决方案不适用于我的情况。

我试图像这样在App.js的Switch中渲染两个组件

     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);
  }
}

问题是带有MyHome组件的Route引发此错误: console logs with error and debug code from Home render

Home组件非常庞大,因此我将在此处仅包括相关代码

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;

Home组件渲染中console.log("Not loading, display articles")中的调试代码显示在控制台中,如此处所示

debug code

但该组件无法渲染。

这是完整的代码 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);

还有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();

我想念什么?

1 个答案:

答案 0 :(得分:0)

react-router中的render道具应该是一个功能:Render props

使用以下两行之一来修复您的代码:

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

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