I have an array of items I would like to create Panels out of which would eventually be inserted into the Accordion.
In one file, I have:
var items = this.state.contents.map(function(content, index) {
return <Content {...content}, key={index}/>
};
return (
<Accordion>
{items}
</Accordion>
);
In another file called Content I have:
return(
<Panel header={this.props.header} eventKey={this.props.key}>
{this.props.body}
</Panel>
);
When I have the Accordion and Panel in the same file, they work. But when I generate the Panel using map after splitting them into two files, it doesn't seem to collapse.
Here is the solution
<Accordion>
{this.item.map(item =>
<AcPanel key={item.id} item={item} eventKey={item.id} />
)}
</Accordion>
In AcPanel Class use {...this.props} for fetch all properties and assign values on your parent class like i used "eventKey={item.id}".
<Panel header={`Collapsible Group Item`} bsClass='class-name' {...this.props}>
content here
</Panel>
I found a solution that lets you use a component in a separate file.
I figured the problem must be to do with the Accordion
not being able to pass some props down to the Panel
because they go to the wrapping component instead, so I tried collecting all the props that weren't mine and passing them to the 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>
);
If you want to specify any props on the Panel
, make sure they go after the collected props so that they take precedence over any defaults:
const { body, ...props } = this.props
return(
<Panel {...props}
bsStyle="info">
{body}
</Panel>
);
If you choose any props names the same as whatever Accordion
is passing to Panel
, you could clobber something and break it - if you're concerned, it should be straightforward to follow the code and see what is being passed on.
react-bootstrap seems to complain if the children of an Accordion are not Panels, and by wrapping Panel inside of my Content class I was doing just that.
To solve this problem I had to step away from React's convention. Rather than creating a class Content, I created another js file rather than a react.js file. By treating this file like a normal js file, I was able to call on a function inside of this file which maps over each 'this.state.contents' and return a Panel object.
This whole file will return an array of Panel class.