Ich habe diese Komponente, welche Rolle ist, um ein Kategorie-Objekt von Server mit Fetch, die ich in ComponentWillMount setzen. Es gibt nur einen setState: Es ist im ComponentWillMount-Callback, wenn die Daten vom Server ankommen.react Komponente rendert zweimal mit nur einem setState in componentWillMount
Das Problem ist, dass die Komponente zweimal rendert, zum ersten Mal this.state.category Wert ist der Ausgangszustand des Konstruktors, dann das zweite Mal this.state.category gleich dem Objekt vom Server erhalten. Wie kann ich die Rendermethode nur einmal aufrufen, direkt nach dem setState?
import ReactDom from 'react-dom';
import React from 'react';
import Breadcrumb from './Breadcrumb';
export default class Category extends React.Component{
constructor(props){
super(props);
this.state = {
category: {
'published_projects':[{'images':[]}],
'unpublished_projects':[{'images':[]}],
}
};
}
componentWillMount(){
fetch(route('api.categories.show', {'slug':this.props.match.params.slug}))
.then(response => response.json())
.then(data => {this.setState({category: data});});
}
totalLikesCount(){
return this.state.category.published_projects.reduce((accu, item) =>
accu + item.likes_count ,0
);
}
totalViewsCount(){
return this.state.category.published_projects.reduce((accu, item) =>
accu + item.views_count ,0
);
}
totalPicturesCount(){
return this.state.category.published_projects.reduce((accu, item) =>
accu + item.images.length ,0
);
}
render(){
const category = this.state.category;
console.log(category);
return (
<div className="w980px center">
<div className="CategoryHeader-bg-wrapper margin-rt10 margin-lt10">
<img alt="" src={category.picture_url}/>
<div className="CategoryHeader-bg-gradient">
<h1>
{ category.name }
</h1>
</div>
</div>
<div className="CategoryHeader-metrics-wrapper u-boxShadow margin-rt10 margin-lt10">
<ul className="CategoryHeader-metrics-list">
<li className="CategoryHeader-metrics-item txt-center">
<span className="CategoryHeader-metrics-label">
Projets
</span>
<span className="CategoryHeader-metrics-value">
{ category.published_projects.length }
</span>
</li>
<li className="CategoryHeader-metrics-item txt-center">
<span className="CategoryHeader-metrics-label">
Total de mentions j'aime
</span>
<span className="CategoryHeader-metrics-value">
{ this.totalLikesCount() }
</span>
</li>
<li className="CategoryHeader-metrics-item txt-center">
<span className="CategoryHeader-metrics-label">
Total des vues
</span>
<span className="CategoryHeader-metrics-value">
{ this.totalViewsCount() }
</span>
</li>
<li className="CategoryHeader-metrics-item txt-center">
<span className="CategoryHeader-metrics-label">
Total des photos
</span>
<span className="CategoryHeader-metrics-value">
{ this.totalPicturesCount() }
</span>
</li>
</ul>
</div>
</div>
);
}
}
Den einzigen Weg, dies zu tun wäre, um die Datenverbindung in einer übergeordneten Komponente zu machen und Mounten Sie die Komponente "Category" erst, wenn die Daten vorhanden sind. Sie können das anfängliche Rendern der Komponente nicht verhindern. Sie können überprüfen, ob die Daten in die render-Methode geladen werden, und "null zurückgeben", wenn sie nicht existiert, aber die Funktion "render" wird immer noch zweimal aufgerufen. –