React bootstrap面板自定义标题 - 展开折叠不起作用

时间:2017-03-06 09:11:41

标签: reactjs react-bootstrap bootstrap-accordion

我正在尝试使用React bootstrap panelgroup(Accordion)

我想要一个带单选按钮的自定义标题。因此我用自定义标题替换了标题。使用自定义标头后,展开折叠已停止工作。

代码(自定义标题)

    constructor(props) {
    super(props);
    this.state = {
        isSelected: false,
    };
}

componentWillMount () {
    if (this.props.isSelected) {
        this.state = {isSelected:true};
    } else {
        this.state = {isSelected: false};
    }        
}

componentWillUpdate () {
    if (this.props.isSelected) {
        this.state = {isSelected:true};
    } else {
        this.state = {isSelected: false};
    }
}    

render() {
    let radio = 
        <span>
            <input type="radio" className="accordion_checkbox" name={this.props.name}  />
            {this.props.header}
        </span> ;
    if (this.state.isSelected) {
        radio = <span>
            <input type="radio" className="accordion_checkbox" defaultChecked name={this.props.name}  />
            {this.props.header}
        </span>
    }
    return (
        <div>
            {radio}
        </div>
    )
}

小组:

            <PanelGroup className="payment-accordion" activeKey={this.state.activeKey} onSelect={e => this.handleSelect(e)} accordion>
                <Panel header={<PanelHeaderCustom name="saved_card" isSelected={this.state.activeKey === "savedCards"} header="SAVED CARD"/>} eventKey="savedCards">
                    <SwipableCards savedCards={this.props.savedCards}/>
                </Panel>
                <Panel header={<PanelHeaderCustom name="debit_card" isSelected={this.state.activeKey === "creditDebitCards"} header="DEBIT CARD"/>} eventKey="creditDebitCards">Debit/Credit Card</Panel>
                <Panel header={<PanelHeaderCustom name="net_banking" isSelected={this.state.activeKey === "netbanking"} header="NET BANKING"/>} eventKey="netbanking">Debit/Credit Card</Panel>
            </PanelGroup>

我缺少什么?

提前致谢

1 个答案:

答案 0 :(得分:0)

使用JSX语法调用元素时,生成的对象类型没有&#34; children&#34;作为道具,我认为react-bootstrap Panel无法正确处理这种情况。

<PanelHeaderCustom /> // returns  Object { type: PanelHeaderCustom(), props: { header:"NET BANKING", isSelected: false, name: "net_banking" } }

因此,作为一种变通方法,您可以将自定义标头包装到Panel标头prop中的div:

class PanelHeaderCustom extends Component {
  render () {
    return (
      <span>
        <input
          type='radio'
          className='accordion_checkbox'
          checked={this.props.isSelected}
          name={this.props.name} />
        {this.props.header}
      </span>
    )
  }
}

export default class Test extends Component {
  constructor (props) {
    super(props)
    this.state = {
      activeKey: ''
    }
  }

  handleSelect (e) {
    this.setState({
      activeKey: e
    })
  }

  render () {
    return (
      <div>
        <PanelGroup
          className='payment-accordion'
          activeKey={this.state.activeKey}
          onSelect={(e) => this.handleSelect(e)}
          accordion>
          <Panel
            header={
              <div>
                <PanelHeaderCustom
                  name='saved_card'
                  isSelected={this.state.activeKey === 'savedCards'}
                  header='SAVED CARD' />
              </div>
            }
            eventKey='savedCards'>
            <div>Example</div>
          </Panel>
          <Panel
            header={
              <div>
                <PanelHeaderCustom
                  name='debit_card'
                  isSelected={this.state.activeKey === 'creditDebitCards'}
                  header='DEBIT CARD' />
              </div>
            }
            eventKey='creditDebitCards'>
            Debit/Credit Card
          </Panel>
          <Panel
            header={
              <div>
                <PanelHeaderCustom
                  name='net_banking'
                  isSelected={this.state.activeKey === 'netbanking'}
                  header='NET BANKING' />
              </div>
            }
            eventKey='netbanking'>
            Debit/Credit Card
          </Panel>
        </PanelGroup>
      </div>
    )
  }
}

ReactDOM.render(
  <Test />,
  document.getElementById('main')
)

作为旁注,我认为你应该让你的自定义标题成为无状态组件,因为组件没有必要知道它自己的状态。只需在PanelHeaderCustom中使用props,并使用主应用程序的状态控制实例。

当您将该组件设置为无状态时,您可以将组件的代码编写为纯函数,而无需进行不必要的div-wrapping:

// Returns { type: "span", props: { children: [ { type: "input"... }, "SAVED_CARD" ] } }
function PanelHeaderCustom (
  header,
  name,
  isSelected
) {
  return (
  <span>
    <input
      type='radio'
      className='accordion_checkbox'
      checked={isSelected}
      name={name} />
    {header}
  </span>
  )
}

然后在Panel&#39的标题中调用该函数:

<Panel
  header={
    PanelHeaderCustom(
      'SAVED CARD',
      'saved_card',
      this.state.activeKey === 'savedCards'
    )
  }
  eventKey='savedCards'>
  <div>Example</div>
</Panel>