I am doing an HTTP request call and don't want to display the page until the response comes back (the request call is getRoadmaps
). I have a redux state called "loading" to determine if the response came back yet? Any insights on how to implement that in my code? My other redux states are roadmap, which contains an object also called roadmap (sorry for the confusion).
I saw a few answers that said to do (psuedo code): if not loaded display loading screen else load the normal screen in render. But my problem doesn't exists in render, but in componentWillMount() where I do
this.props.getRoadmaps()
and then 3 lines later where I do
console.log(this.displayRoadmap[0].roadmap[0])
which should successfully log the roadmap if getRoadmaps() finished, it seems like getRoadmaps() is called but then the program continues without getRoadmaps() completely finishes, which causes my displayRoadmap to be undefined.
This also leads to some weird phenomenon like if I go from one screen into this component it always works but if I refresh the page it doesn't work.
import React, { Component } from "react";
import Tree from "./Tree";
import TreeSidebar from "./TreeSidebar";
import { withRouter } from "react-router-dom";
import { connect } from "react-redux";
import { getRoadmaps } from "../actions/roadmapAction";
class OneRoadmap extends Component {
constructor(props) {
super(props);
this.state = {
loading: this.props.roadmap.loading,
roadmapName: "click a white circle to show more!",
roadmapImg:
"https://cdn3.iconfinder.com/data/icons/harmonicons-06/64/plus-circle-512.png",
roadmapDetail: [{ text: "Click on something" }, { text: "hi" }],
treeData: //deleted,just the default big json object
};
}
componentWillMount() {
this.props.getRoadmaps();
var location1 = this.props.location.pathname;
var n = location1.slice(9);
var current_roadmaps = this.props.roadmap.roadmaps;
this.displayRoadmap = current_roadmaps.filter(
eachRoadmap => eachRoadmap._id == n
);
// now we have a roadmap
console.log(this.displayRoadmap[0].roadmap[0]);
this.setState({ treeData: this.displayRoadmap[0].roadmap[0] });
console.log("is good");
console.log(this.props.loading);
}
componentDidMount() {}
handle_on_click_change = d => {
this.setState({ roadmapName: d.data.name });
this.setState({ roadmapImg: d.data.img });
if (d.data.details == undefined) {
this.setState({
roadmapDetail: [{ text: "The author did not put anything here" }]
});
} else {
this.setState({ roadmapDetail: d.data.details });
}
};
render() {
return (
<div>
{console.log(this.state.loading)}
<ul>
<li styles={{ float: "left" }}>
<div>
{console.log(this.state.treeData)}
<Tree
on_click_change={this.handle_on_click_change}
roadmapData={this.state.treeData}
/>
</div>
</li>
<li styles={{ float: "right" }}>
<div>
<TreeSidebar
displayName={this.state.roadmapName}
displayImg={this.state.roadmapImg}
displayDetail={this.state.roadmapDetail}
/>
</div>
</li>
</ul>
</div>
);
}
}
const mapStateToProps = state => ({
roadmap: state.roadmap
});
export default connect(
mapStateToProps,
{ getRoadmaps }
)(OneRoadmap);
Personally, how I do this I use CSS styles I don't know if this if the best approach to do this but it works for me, I will do something like this
this state = {
loaderStyle: 'block',
contentStyle: 'none'
}
componentDidMount() {
If(this.displayRoadmap[0].length > 0) {
this.setsState({loaderStyle: 'none', contentStyle:
'block:
} else /// do something
};
In my render function, I will do this
<Loader style={{display: this.state.loaderStyle}}/>
<Content style={{display: this.state.contentStyle}}>.
</Content>