我导入子组件并在我的app.js
文件中呈现它。该组件有一个console.log
用于调试,但它一直在运行日志,似乎没有结束。担心某些事情可能是错误的,是ReactJS的新手,并想知道这是否是一个常见问题以及如何解决它。
App.js:
import React, { Component } from 'react';
import {BrowserRouter as Router, Link} from 'react-router-dom';
import './App.css';
import axios from 'axios'
import Header from './components/header';
import Page from './components/page';
class App extends Component {
constructor(props) {
super(props);
this.state = {
title: 'John Doe',
nav: {},
currentPage: "",
pageContent: "",
pageTitle: "",
pageTemplate: "",
pageId: 0,
pageCustomMeta: {},
archiveData: []
}
}
getMainMenu(){
axios.get('http://admin.sitedata.co/menus/5')
.then((response) => {
this.setState({nav:response.data});
})
.catch((error) => {
console.log(error);
});
}
isHome(){
//console.log(document.location.pathname);
if(document.location.pathname === "/") {
document.body.classList.add('home');
} else {
document.body.classList.remove('home');
}
}
componentDidMount(){
/*
* get current page content
* get the main menu
* allow pageChange function to be ran
* allow isHome to be ran
*/
var slug = "";
if(document.location.pathname === "/") {
slug = "home";
} else {
slug = document.location.pathname.substr(1);
}
this.getPageData(slug);
this.getMainMenu();
this.pageChange = this.pageChange.bind(this);
this.isHome = this.isHome.bind(this);
this.triggerMenu = this.triggerMenu.bind(this);
this.triggerHire = this.triggerHire.bind(this);
this.navigate = this.navigate.bind(this);
this.setArchiveData = this.setArchiveData.bind(this);
this.resetArchiveData = this.resetArchiveData.bind(this);
this.madeChange = this.madeChange.bind(this);
//document.getElementById('loadingOverlay').classList.add('remove');
}
getPageData(slug){
console.log(this.state);
axios.get('http://admin.sitedata.co/pages?slug='+slug)
.then((response) => {
console.log(response.data);
this.setState({
pageContent:response.data[0].content.rendered,
currentPage:slug,
pageTitle:response.data[0].title.rendered,
pageTemplate:response.data[0].template,
pageId:response.data[0].id,
pageCustomMeta:response.data[0].post_meta,
archiveData:[]
},function(){
console.log(this.state);
/*
* set the page title
* check if the page is at home
* get page custom meta
*/
document.title = this.state.pageTitle;
this.isHome();
});
})
.catch((error) => {
console.log(error);
});
}
pageChange(e){
var slug = e.target.getAttribute('data-link');
var classes = e.target.classList.contains('trigger-hire');
if(classes){
this.triggerHire();
e.preventDefault();
} else {
this.getPageData(slug);
}
}
setArchiveData(archives) {
this.setState({archiveData:archives});
}
resetArchiveData() {
}
navigate (event) {
event.preventDefault()
console.log(event.target.tagName);
if (event.target.tagName === 'A') {
this.props.router.push(event.target.getAttribute('href'));
console.log('boom');
}
event.preventDefault();
}
triggerMenu(e){
var menuOverlay = document.getElementById('menuOverlay');
if(menuOverlay.classList.contains('active')){
menuOverlay.classList.remove('active');
} else {
menuOverlay.classList.add('active');
}
}
triggerHire(e){
var hireOverlay = document.getElementById('hireOverlay');
if(hireOverlay.classList.contains('active')){
hireOverlay.classList.remove('active');
} else {
hireOverlay.classList.add('active');
}
e.stopPropagation();
e.preventDefault();
}
madeChange(){
alert('changed');
}
render() {
return (
<div className="App">
<Header nav={this.state.nav} pageChange={this.pageChange} triggerMenu={this.triggerMenu} triggerHire={this.triggerHire}/>
<Page madeChange={this.madeChange}
currentPage={this.state.currentPage}
nav={this.state.nav}
pageChange={this.pageChange}
isHome={this.isHome}
pageContent={this.state.pageContent}
pageTitle={this.state.pageTitle}
pageTemplate={this.state.pageTemplate}
pageId={this.state.pageId}
pageCustomMeta={this.state.pageCustomMeta}
archiveData={this.state.archiveData}
triggerHire={this.triggerHire}
navigate={this.navigate}
setArchiveData={this.setArchiveData}
/>
</div>
);
}
}
export default App;
Page.js
import React, { Component } from 'react';
import {BrowserRouter as Router, Link} from 'react-router-dom';
import axios from 'axios'
class Page extends Component {
render() {
if(this.props.currentPage){
var currentPage = this.props.currentPage;
var pageChange = this.props.pageChange;
var customMeta = this.props.pageCustomMeta;
var pageTempalate = this.props.pageTemplate.substr(0,this.props.pageTemplate.length-4);
var pageTitle = this.props.pageTitle;
var newTitle = <h1><span><i>{pageTitle}</i></span></h1>;
var isArchive = "";
var archiveName = "";
var firstSpace = pageTitle.indexOf(' ');
if(firstSpace > -1){
var firstWord = pageTitle.substr(0, firstSpace);
var titleLast = pageTitle.substr(firstSpace);
newTitle = <h1><span><i>{firstWord}</i>{titleLast}</span></h1>
}
if(currentPage === "home"){
if(this.props.nav.items){
var navData = this.props.nav;
var navHomeItems = navData.items.map(function(navItem){
return <li key={navItem.id}><Link to={'/'+navItem.object_slug} className={navItem.classes} onClick={pageChange} data-link={navItem.object_slug}>{navItem.title}</Link></li>;
});
}
}
document.title = this.props.pageTitle;
var isArchive = customMeta.isArchive;
var archiveName = customMeta.archiveName
var worksArchive = "";
if(customMeta.isArchive && customMeta.isArchive == "true"){
if(customMeta.archiveName) {
axios.get('http://admin.sitedata.co/'+customMeta.archiveName)
.then((response) => {
var archivePages = response.data;
console.log(archivePages);
if(archiveName == "works"){
worksArchive = archivePages.map(function(work){
//console.log(worksArchive);
return <Link key={work.id} className="work-item" to="/" ><img src={work.post_meta.targetimg} /></Link>;
});
this.props.setArchiveData(worksArchive);
}
})
.catch((error) => {
console.log(error);
});
}
}
if(customMeta.pageColor){
document.body.classList.add(customMeta.pageColor);
}
if(customMeta.bgimg){
document.body.setAttribute('style', "background-image:url('"+customMeta.bgimg+"');");
}
}
return (
<Router onEnter={this.props.madeChange}>
<div className="container">
<div className={(pageTempalate !== "") ? pageTempalate : ''}>
{newTitle}
<div dangerouslySetInnerHTML={{__html:this.props.pageContent}}></div>
{this.props.archiveData}
</div>
</div>
</Router>
);
}
}
export default Page;
答案 0 :(得分:0)
将代码提炼为基本代码,如下所示:
class Page extends Component {
render() {
axios.get(url).then(response=> {
this.setState({archiveData: response.data})
})
return (
<div className="container">
{this.state.archiveData}
</div>
)
}
}
(您使用回调导致父母发送新道具的方式不同,但效果相同)。
你现在应该能够看到问题:渲染方法会导致对状态(或道具)的延迟更改,它会在响应中触发新的渲染。所以你现在有一个无限循环,只是延迟了ajax请求所花费的时间。
要解决此问题,您需要从render方法中删除ajax请求。在您的情况下,它可能应该在父App
组件中。