【问题标题】:react-bootstrap modal, how to handle child component?react-bootstrap modal,如何处理子组件?
【发布时间】:2017-04-03 04:55:21
【问题描述】:

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

顺便说一句,我也在使用fixed-data-table,所以数据(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');
  }
}

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

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

【问题讨论】:

    标签: reactjs react-bootstrap react-modal


    【解决方案1】:

    好的,让我继续前进的部分答案在这里: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>;
    }
    

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

    附录:就是这样的作品。实际上需要知道宽度的子组件是从 Modal 主体向下的几个级别,因此它需要知道其直接父级的宽度... grrr 应该如何反应组件知道他们的容器方向??

    【讨论】:

      猜你喜欢
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 2022-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      • 2016-06-08
      相关资源
      最近更新 更多