react-bootstrap 手风琴不随地图折叠

react-bootstrap Accordion not collapsing with map

我有一组项目,我想创建面板,最终将把这些面板插入到 Accordion 中。

在一个文件中,我有:

var items = this.state.contents.map(function(content, index) {
  return <Content {...content}, key={index}/>
};

return (
  <Accordion>
    {items}
  </Accordion>
);

在另一个名为 Content 的文件中我有:

return(
  <Panel header={this.props.header} eventKey={this.props.key}>
    {this.props.body}
  </Panel>
);

当我将 Accordion 和 Panel 放在同一个文件中时,它们就可以工作了。但是当我将它们拆分成两个文件后使用地图生成面板时,它似乎并没有崩溃。

react-bootstrap 似乎抱怨手风琴的子项不是面板,并且通过将面板包装在我的内容中 class 我就是这样做的。

为了解决这个问题,我不得不脱离 React 的惯例。我没有创建 class 内容,而是创建了另一个 js 文件而不是 react.js 文件。通过像处理普通 js 文件一样处理此文件,我能够调用此文件内部的函数,该函数映射每个 'this.state.contents' 和 return 一个 Panel 对象。

整个文件将 return 面板数组 class。

我找到了一个解决方案,可以让您在单独的文件中使用组件。

我认为问题一定与 Accordion 无法将某些道具传递给 Panel 有关,因为它们转到了包装组件,所以我尝试收集所有不是我的道具并将它们传递给面板:

// make sure you have all your own props specified before ...props
// so that they can't mess up the panel.
const { body, ...props } = this.props

return(
  <Panel {...props}>
    {body}
  </Panel>
);

如果您想在 Panel 上指定任何道具,请确保它们遵循收集的道具,以便它们优先于任何默认值:

const { body, ...props } = this.props

return(
  <Panel {...props}
         bsStyle="info">
    {body}
  </Panel>
);

如果您选择与 Accordion 传递给 Panel 的任何道具名称相同的道具名称,您可能会破坏某些东西并破坏它 - 如果您担心,遵循代码并查看正在传递的内容。

这是解决方案

<Accordion>
  {this.item.map(item =>
     <AcPanel key={item.id} item={item} eventKey={item.id} />
  )}
</Accordion>

在 AcPanel Class 中使用 {...this.props} 获取所有属性并为您的父级 class 分配值,就像我使用的 "eventKey={item.id}".

<Panel header={`Collapsible Group Item`} bsClass='class-name' {...this.props}>
content here
</Panel>

对于使用 Accordion.Toggle 的任何人,这就是我让手风琴在地图上折叠的方式。

在Accordion的父组件中,给状态添加一个activeKey值。创建一个函数来处理将在映射期间传递给手风琴的每个子组件的活动键更改。请务必将该函数绑定到父组件。

this.state = {
  items = []
  activeKey: ''
}

handleActiveKeyChange = activeKey => {
  if (this.state.activeKey === activeKey) {
    //allows us to close expanded item by clicking its toggle while open
    activeKey = -1
  }
  this.setState({ activeKey })
}

在您的渲染方法中传递活动键状态和功能:

<Accordion activeKey={this.state.activeKey}>
  {this.state.items.map((item, index) => (
    <Item eventKey={index} handleActiveKeyChange={this.handleActiveKeyChange} />
  ))}
</Accordion

在您的子(项目)元素的手风琴切换中,添加传递的函数和道具:

<Card>
  <Card.Header>
    <Accordion.Toggle
      eventKey={this.props.eventKey}
      onClick={() => this.props.handleActiveKeyChange(this.props.eventKey)}
    >
      //+ icon here
    </Accordion.Toggle>
  </Card.Header>
  //card content here 
</Card

最简单的方法是在 eventKey 参数中设置条件。

 <Card key={item.id}> 
    <Card.Header>
      <Accordion.Toggle as={Button} variant="link" eventKey={index === 0 ? '0' : index}>
        {item.title} 
      </Accordion.Toggle>
    </Card.Header>
    <Accordion.Collapse eventKey={index === 0 ? '0' : index}>
      <Card.Body>
             CARD BODY
      </Card.Body>
    </Accordion.Collapse>
  </Card>