As you know React components render in parallel. There is no guarantee in order that they finish rendering.
I want to render the following components in this exact order:
. I need this header to render first so that I can act on it in my other two components after rendered. I am going to run some JS on it, etc. later on from those other two component's componentDidMount so that's why I want this to render first)
Here is a little more context https://youtu.be/OrEq5X9O4bw
I tried a bunch of stuff as you can see with the lifecycle methods, which is probably totally wrong or not even sure it's what people are even doing for this sort of scenario, but no luck so far.
const Main = Component({
getInitialState() {
console.log("getInitialState being called");
return null;
},
renderMe() {
console.log("changed InterviewContent's state");
this.setState({renderInk: true});
},
componentDidMount() {
console.log("InterviewContentMain mounted");
},
render(){
var company = this.props.company;
return (
<div id="ft-interview-content">
<p className="section-heading bold font-22" id="interview-heading">Interview</p>
<InterviewContent renderMe={this.renderMe} company={company}/>
</div>
)
}
})
export default InterviewContentMain;
const InterviewContent = Component({
componentDidMount() {
console.log("InterviewContent mounted");
},
renderMe() {
console.log("changed InterviewContent's state");
this.setState({subParentRendered: true});
},
render(){
var company = this.props.company;
return (
<div id="interview-content" className="clear-both">
<div className="column-group">
<div className="all-20">
<TableOfContents renderHeader={this.props.renderMe} renderContent={this.renderMe} company={company}/>
</div>
<div className="all-80">
<InterviewContainer company={company}/>
</div>
</div>
</div>
)
}
})
const TableOfContents = Component({
enableInk() {
new Ink.UI.Sticky(el, {topElement: "#interview-heading", bottomElement: "#footer"});
},
componentDidMount() {
console.log("table of contents mounted");
this.renderHeader;
this.renderContent;
enableInk(); // I only want to run this if the Header and the Content have rendered first
},
render(){
return (
<div>
<p className="margin-8"><span className="blue medium"><Link to="/">HOME</Link></span></p>
)
}
})
UPDATE:
here's what I tried. While they all 3 render, I'm still getting times where TableOfContents renders before InterviewContentMain or InterviewContent which means TableOfContent after rendered overlaps <p className="section-heading bold font-22" id="interview-heading">Interview</p>
instead of rendering underneath it due to the sticky JS I tried to apply in TableOfContents
const InterviewContentMain = Component({
getInitialState() {
console.log("getInitialState being called");
return {rendered: false};
},
componentDidMount() {
console.log("InterviewContentMain mounted")
this.setState({rendered: true});
},
render(){
var company = this.props.company;
return (
<div id="ft-interview-content">
<div className="section-heading bold font-22" id="interview-heading">Interview</div>
{ this.state.rendered && <InterviewContent company={company}/> }
</div>
)
}
})
export default InterviewContentMain;
const InterviewContent = Component({
getInitialState() {
console.log("getInitialState being called");
return {rendered: false};
},
componentDidMount() {
console.log("InterviewContent mounted")
this.setState({rendered: true});
},
render(){
var company = this.props.company;
return (
<div id="interview-content" className="clear-both">
<div className="column-group">
<div className="all-20">
<TableOfContents company={company}/>
</div>
<div className="all-80">
<InterviewContainer company={company}/>
</div>
</div>
</div>
)
}
})
const TableOfContents = Component({
componentDidMount() {
const el = ReactDOM.findDOMNode(this);
new Ink.UI.Sticky(el,{topElement: "#interview-heading", bottomElement: "#footer"});
console.log("TableOfContents mounted");
},
render(){
return (
<div>
<p className="margin-8"><span className="blue medium"><Link to="/">HOME</Link></span></p>
</div>
)
}
})
If you want to conditionally render a component, wrap it in a conditional (whether a function or an inline boolean expression)
You say:
TableOfContents (should only render after InterviewContainer and InterviewContentMain have rendered)
.. so inside the render
method of TableOfContents
parent container, check whether some values are true, like you would in an if
statement.
render(){
var company = this.props.company;
return (
<div id="interview-content" className="clear-both">
<div className="column-group">
<div className="all-20">
{this.state.subParentRendered &&
<TableOfContents renderHeader={this.props.renderMe} renderContent={this.renderMe} company={company}/>
}
</div>
<div className="all-80">
<InterviewContainer company={company}/>
</div>
</div>
</div>
)
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments