How can I share data between repeating elements in React?
So, I'm trying to create an extensible map component using React. I installed it as shown below. Everything is working now, I can click on the map to expand it and click on it again to collapse it. Each card has its own "advanced" state variable
var ExpandableListItem = React.createClass({
toggleCard: function(){
var self = this
this.setState({
expanded: !self.state.expanded
})
},
getInitialState: function(){
return {
expanded: false
}
},
render: function(){
return (
<Card onTouchTap={this.toggleCard}>
<CardText>
{this.state.expanded ? 'Expanded Card' : 'Normal Card'}
</CardText>
</Card>
)
}
})
var CardList = React.createClass({
render: function(){
return (
<div>
{this.props.repeatEntity.map(function(element, index) {
return (
<ExpandableListItem text={element[index].week}></ExpandableListItem>
)}
)}
</div>
)
}
})
What I want to have is only one card open at a time, that is, if it is open and you press another, the first one should close.
I tried to use a global variable with an extension, but the state variables are not two-way (like in Angular), so I cannot change the state value of one card from another one.
Can anyone please help? Thank.
source to share
SOLUTION . Let the parent component handle all extended states.
AS? Store the expanded
state foreach element in its parent component ( CardList
). You can store states in a separate array with the same length as repeatEntity
and map them to, for example, the index for the correct entity.
array = [true, false, false]; // [0. expanded state, 1. ..., 2. ...]
entities = [{...}, {...}, {...}]; // [0. entity, 1. ..., 2. ...]
Alternatively, you can add a variable expanded
to each entity
. Then you need to implement a callback function that takes the information you need to identify the toggled parameter entity
as a parameter. This will be the index or the object itself entity
. The callback function can then change the consistent state of the expanded
past entity
.
handleCardItemToggle(entityIndex) {
const expandedStates = this.state.entityStates;
// set all values to 'false'
expandedStates[entityIndex] = !expandedStates[entityIndex]; // toggle expanded-state of item
this.setState({
entityStates: expandedStates
});
}
At the very least, you need to pass a callback and an index to all elements.
render: function(){
return (
<div>
{this.props.repeatEntity.map(function(element, index) {
return (
<ExpandableListItem id={index} isExpanded={this.state.entityStates[index]} handleToggle={this.handleCardItemToggle} text={element[index].week}></ExpandableListItem>
)}
)}
</div>
)
}
// in ExpandableListItem
toggleCard() {
this.props.handleToggle(this.props.id);
}
NOTE . There may be syntax or semantic errors. However, this approach should solve your problem.
source to share