简体   繁体   English

react-bootstrap modal,如何处理子组件?

[英]react-bootstrap modal, how to handle child component?

I'm using a Modal based on the example code from the docs: https://react-bootstrap.github.io/components.html#modals-live . 我正在使用基于文档示例代码的Modal: 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. 我想要的是仅在1)它的数据准备好了,以及2)在打开模态时才渲染子组件。 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). 另外,子组件需要知道它必须处理多大的区域(因为它正在内部进行d3.js svg绘制)。

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: 我也是,顺便说一句,使用fixed-data-table ,因此数据(一个concept )处于状态,并且在单击行时打开Model:

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. 根据Modal docs示例,Modal位于渲染中,并以关闭状态存在于DOM中,直到有人打开它为止。 However, the Modal.Body doesn't seem to exist till the Modal is open. 但是,直到Modal打开,Modal.Body才似乎不存在。 My bright idea is that the child, ConceptDetail , can get the ClientWidth from a ref to its containing div. 我聪明的主意是,子级ConceptDetail可以从ref到其包含div的ClientWidth。

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. 起作用,除了ref直到子组件被渲染之后才准备就绪。 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. 当我单击一行时,我看到警报will update, no modalBody ref ,警报did update, width: 868 ,然后显示子组件。 But the child didn't get the width (or the updated ref) because it actually renders before the componentDidUpdate . 但是子级没有获得宽度(或更新的ref),因为它实际上是在componentDidUpdate之前呈现的。 The reason I see the alert first (I assume) is because the Modal is animated and doesn't appear instantly on rendering. 我首先看到警报的原因(我认为)是因为Modal具有动画效果,并且在渲染时不会立即出现。 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. 当我关闭Modal时,我确实确实看到了快速闪光,它终于收到了正确的宽度,但是到那时我不再需要它了。

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. 如果有人能解释正确的方法来做我通常要做的事情,我将不胜感激:触发带有子组件的Modal的显示,该子组件希望接收数据和容器尺寸作为道具。

Ok, so a partial answer that got me going is here: Trigger modal shown for React Bootstrap 好的,下面让我继续的部分答案是: React Bootstrap的触发模式

So, onEntered doesn't fire till the modal is all ready, so that's the time to get the width: 因此,在模态全部准备就绪之前, onEntered不会触发,因此是时候获取宽度了:

<Modal ... 
    onEntered={(() => {
      let { clientWidth } = this.refs.modalBody;
      if (this.state.modalWidth !== clientWidth)
        this.setState({modalWidth:clientWidth});
    }).bind(this)}>
...
  <Modal.Body>
    <div ref="modalBody">
      {this.getConceptDetail()}
    </div>
  </Modal.Body>
...
</Modal>

Then a separate method to get the child component (if ready): 然后是一个单独的方法来获取子组件(如果准备就绪):

getConceptDetail() {
  const {concept, modalWidth} = this.state;
  if (concept && modalWidth) {
    let conceptId = concept.records[0].rollupConceptId;
    return <ConceptDetail 
              width={modalWidth}
              concept={concept} 
              conceptId={conceptId}/>;
  }
  return <h3>no concept detail</h3>;
}

This isn't terrible, I guess, and it works. 我猜这并不可怕,并且可以正常工作。 If someone knows a better way to structure it, I'd be happy to hear. 如果有人知道更好的组织方式,我很高兴听到。

ADDENDUM: Sort of works, that is. 附录:就是这样的作品。 The child component that actually needs to know the width is a couple levels down from the Modal body, so it needs to know the width of its direct parent... grrr How are react components supposed to know their container directions?? 实际上需要知道宽度的子组件比Modal主体低了几个,因此它需要知道其直接父组件的宽度... grrr react组件应该如何知道它们的容器方向?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM