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

时间:2016-11-19 11:27:18

标签: reactjs react-bootstrap react-modal

我正在使用基于文档示例代码的模态:https://react-bootstrap.github.io/components.html#modals-live。我想要的是只有当1)它的数据准备就绪时才会呈现子组件,2)当模态打开时。此外,子组件需要知道它必须使用的区域有多宽(因为它在内部进行了一些d3.js svg绘制)。

我也是,顺便说一句,使用fixed-data-table,因此数据(a concept)处于状态,并且在行点击时打开模型:

onRowClick={(evt, idx, obj)=>{
  let concept = filteredDataList.getObjectAt(idx);
  this.openModal();
  this.setState({concept});
}}

根据Modal docs示例,Modal位于渲染中,并以封闭状态存在于DOM中,直到某些东西打开它。但是,在Modal打开之前,Modal.Body似乎不存在。我的好主意是,孩子ConceptDetail可以将客户端宽度从引用转到其包含的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>

这个工作,除了在渲染子组件之后ref尚未就绪。为了弄清楚发生了什么,我这样做了:

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');
  }
}

当我点击一行时,我会看到提醒will update, no modalBody ref,然后是提醒did update, width: 868,然后会显示子组件。但是孩子没有得到宽度(或更新的ref),因为它实际上是在componentDidUpdate之前渲染的。我首先看到警报的原因(我假设)是因为Modal是动画的,并且在渲染时不会立即出现。当我关闭Modal时,我确实看到快速闪光它最终获得了正确的宽度,但此时我不再需要它了。

所以,最具体地说,我的问题是:如何将模态的子组件通知模态体的宽度?如果有人可能会解释我正在尝试做的事情的正确方法,我会更感激:触发显示一个Modal,其子组件想要接收数据和容器尺寸作为道具。

1 个答案:

答案 0 :(得分:0)

好的,所以让我走的部分答案就在这里:Trigger modal shown for React Bootstrap

所以,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>

然后一个单独的方法来获取子组件(如果准备好):

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>;
}

我想,这并不可怕,而且有效。如果有人知道更好的结构方式,我会很高兴听到。

ADDENDUM:一系列作品,即。实际需要知道宽度的子组件比Modal主体低几个级别,所以它需要知道其直接父级的宽度... grrr 如何反应组件知道他们的集装箱方向吗?