简体   繁体   English

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

[英]React route doesn't load component even if the component is rendering

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. 免责声明:我已经看到react-router没有呈现任何内容,并且您可能忘记了从定义文件中导出组件,或者您可能混淆了默认导入和命名导入,但是其中的解决方案不适用于我的情况。

I am trying to render two component in a Switch in App.js like this 我试图像这样在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);
  }
}

The problem is that the Route with the MyHome component throws this error: console logs with error and debug code from Home render . 问题是带有MyHome组件的Route会引发此错误: 控制台记录了错误,并从Home render调试了代码

The Home component is huge so I`ll include just the relevant code here 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;

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 可以在console.log("Not loading, display articles") Home组件渲染器中console.log("Not loading, display articles")中的调试代码,如此处所示

debug code 调试代码

but the component does not render. 但该组件无法渲染。

Here is the full code for App.js 这是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 还有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? 我想念什么?

The render props in react-router is supposed to be a function : Render props react-router中的render props应该是一个函数: render props

Use either of the two following lines to fix your code: 使用以下两行之一来修复您的代码:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM