I'm using a Modal based on the example code from the docs: https://react-bootstrap.github.io/components.html#modals-live. What I want is for a child component to be rendered only when 1) it's data is ready, and 2) when the modal is opened. Also, the child component needs to know how wide the area is it has to work with (because it's doing some d3.js svg drawing inside).
I'm also, btw, using fixed-data-table
, so the data (a concept
) is put in state and the Model is opened on row click:
onRowClick={(evt, idx, obj)=>{
let concept = filteredDataList.getObjectAt(idx);
this.openModal();
this.setState({concept});
}}
As per the Modal docs example, the Modal sits there in the render and exists in the DOM in a closed state until something opens it. However, the Modal.Body doesn't seem to exist till the Modal is open. My bright idea is that the child, ConceptDetail
, can get the ClientWidth from a ref to its containing div.
let conceptDetail = '';
if (this.state.concept) {
conceptDetail = <ConceptDetail
containerRefs={this.refs}
concept={concept} />/
}
<Modal>
...
<Modal.Body>
<div ref="modalBody" style={{width:'100%'}}>
{conceptDetail}
</div>
</Modal.Body>
...
</Modal>
This would work, except the ref isn't ready until after the child component is rendered. To figure out what's going on, I did this:
componentWillUpdate(){
if (this.refs.modalBody) {
let { clientWidth } = this.refs.modalBody;
alert(`will update, width: ${clientWidth}`);
} else {
alert('will update, no modalBody ref');
}
}
componentDidUpdate(){
if (this.refs.modalBody) {
let { clientWidth } = this.refs.modalBody;
alert(`did update, width: ${clientWidth}`);
} else {
alert('did update, no modalBody ref');
}
}
When I click a row, I see the alert will update, no modalBody ref
, followed by the alert did update, width: 868
, and then the child component displays. But the child didn't get the width (or the updated ref) because it actually renders before the componentDidUpdate
. The reason I see the alert first (I assume) is because the Modal is animated and doesn't appear instantly on rendering. When I close the Modal, I actually do see for a quick flash that it has finally received the correct width, but at that point I don't need it anymore.
So, most specifically, my question is: How can a child component of a Modal be informed of the modal body's width? I would be even more grateful if someone might explain the right way to do what I'm trying to do in general: Trigger display of a Modal with a child component that would like to receive data and container dimensions as props.