免责声明:我见过react-router is not rendering anything和You 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")
中的调试代码显示在控制台中,如此处所示
但该组件无法渲染。
这是完整的代码 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();
我想念什么?
答案 0 :(得分:0)
react-router中的render
道具应该是一个功能:Render props
使用以下两行之一来修复您的代码:
<Route exact path ='/' render={() => <MyHome/>}/>
<Route exact path ='/' component={<MyHome}/>