Reputation: 9194
This is part of a parent component that gets some px measurements between elements after the child component has rendered:
componentDidMount() {
// get the element where print area resides
let iframe = document.getElementById('ifmcontentstoprint').contentWindow.document.body;
// get the list of elements
let printArea = iframe.querySelectorAll('#printarea');
let positionTitle = iframe.querySelectorAll('#printarea .position-title, .position-title-print');
let pageFooter = iframe.querySelectorAll('#printarea tr.footer');
// total number of pages
var i = positionTitle.length;
// the position of the printarea within the the element
let printAreaPos = printArea[0].getBoundingClientRect().top
// iterate through the elements that are pairs
for (let i = 0; i <= positionTitle.length - 1; i++) {
console.log(pageFooter[i].getBoundingClientRect().top - positionTitle[i].getBoundingClientRect().top);
pageFooter[i].style.marginTop = '50px';
}
}
Where the pageFooter[i].style.marginTop = '50px';
is that will eventually be programmatically set. Just working with static a number for now for testing purposes.
This is part of the child component where the style is supposed to be added:
<tr className='footer'>
<td id='hide'>
<div>
<div align='left' className='footer-columns'>
<p className='effective-date'>DATE EFFECTIVE: {this.props.effectiveDate}</p>
<p>© THE COMPANY</p>
<p>UNAUTHORIZED REPRODUCTION OR DISTRIBUTION PROHIBITED</p>
</div>
<div align='center' className='footer-columns middle-column'>
<p>{this.props.surveyName}</p>
<p>Page {i === 2 ? 1 : i === 5 ? 2 : i === this.props.totalCuts ? this.props.maxPages : null} of {this.props.maxPages}</p>
</div>
<div align='right' className='footer-columns'><img src={logo} alt='The Company Logo' /></div>
</div>
</td>
</tr>
I wasn't seeing why pageFooter[i].style.marginTop = '50px';
wasn't being reflected, but when I changed the <tr className='footer' style={{ marginTop: '50px' }}>
it did work even though it looked like it was rendering the same HTML.
So I finally figured out the modifications being done in the componentDidMount()
where not getting added back to the DOM--they were just hanging out in memory basically.
How should I get this sent back to the DOM?
I eventually want to be able to do pageFooter - positionTitle
position comparisons which requires the child component to render first to get the measurement.
Upvotes: 1
Views: 872
Reputation: 411
At a first glance I can't figure out why what you coded doesn't work. I'm simply going to provide another way to look at this, which is by letting React control the marginTop of the elements itself. To do that, we must use the component's state to store the desired margins, and then use {{ marginTop: measurement }}
as you indicated. Here is a possible outline of such approach:
class YourComponent extends React.Component {
constructor(props) {
super(props);
this.state = { margins: [] };
}
componentDidMount() {
// same as your previous code ...
const newMargins = [];
for (let i = 0; i <= positionTitle.length - 1; i++) {
newMargins.push('50px');
}
this.setState({ margins: newMargins });
}
render() {
const { margins } = this.state;
// and finally, you somehow make margins[index] reach your
// child component (the exact implementation depends on how
// your component is structured)
<tr className="footer" style={{ marginTop: margins[myIndex] }} />
}
}
Upvotes: 1
Reputation: 2316
The style property is used to style DOM elements not any variable or array.
So, when you are doing this: pageFooter[i].style.marginTop = '50px';
you are not targeting the DOM element but a element in the array. To accomplish this you can do: iframe.querySelectorAll('#printarea tr.footer')[i].style.marginTop = '50px'
instead.
Upvotes: 0