0

我正在使用基于文档中的示例代码的模态: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 文档示例,Modal 位于渲染中,并以关闭状态存在于 DOM 中,直到有东西打开它。但是,在 Modal 打开之前,Modal.Body 似乎并不存在。我的好主意是孩子ConceptDetail可以从 ref 获取 ClientWidth 到其包含的 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');
  }
}

当我单击一行时,我会看到 alert will update, no modalBody ref,然后是 alert did update, width: 868,然后显示子组件。但是孩子没有得到宽度(或更新的参考),因为它实际上是在componentDidUpdate. 我首先看到警报的原因(我假设)是因为 Modal 是动画的并且不会在渲染时立即出现。当我关闭模态框时,我确实看到它终于收到了正确的宽度,但我不再需要它了。

所以,最具体地说,我的问题是:如何通知模态的子组件模态体的宽度?如果有人能解释做我通常想做的事情的正确方法,我将更加感激:触发带有子组件的模态显示,该子组件希望接收数据和容器尺寸作为道具。

4

1 回答 1

0

Ok, so a partial answer that got me going is here: Trigger modal shown for React Bootstrap

So, onEntered doesn't fire till the modal is all ready, so that's the time to get the width:

<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??

于 2016-11-19T12:10:40.403 回答