У меня есть Card.Group с приходящими картами на моей странице React.Когда элементы, создающие карты, обновляются, порядок не поддерживается, что вызывает перетасовку элементов на экране.
Я уже пытался добавить ключевое свойство к каждой карте с уникальным и неизменным значением.Я также пытался отсортировать массив перед отображением.
class AlertsView extends React.Component {
constructor(props) {
super(props);
this.state = {
saveDimmerActive: false,
deleteConfirmIsOpen: false,
activeIndex: -1,
filterVisible: false,
filterName: null,
filterVariable: null,
filterRecipients: null,
filterActive: null,
filterStations: null
};
}
render () {
return (
<LayoutWithSidebar view='page-alerts'>
{this.renderCode()}
</LayoutWithSidebar>
)
}
renderCode() {
var panels = null;
if (this.props.alerts) {
panels = this.props.alerts
.map((a, index) => {
let id = a.ID.toString();
if (a.TimeWindowStart) {
var dd = new Date(a.TimeWindowStart * 1000);
dd.setTime(dd.getTime() - dd.getTimezoneOffset() * 60 * 1000);
var tws =
dd.getHours().toString() +
":" +
(dd.getMinutes() < 10 ? "0" : "") +
dd.getMinutes().toString();
} else {
var tws = null;
}
if (a.TimeWindowEnd) {
dd = new Date(a.TimeWindowEnd * 1000);
dd.setTime(dd.getTime() - dd.getTimezoneOffset() * 60 * 1000);
var twe =
dd.getHours().toString() +
":" +
(dd.getMinutes() < 10 ? "0" : "") +
dd.getMinutes().toString();
} else {
var twe = null;
}
var thresholdUnit = "";
switch (a.Variable) {
case "Rain":
thresholdUnit = "mm/h";
break;
case "Temperature":
thresholdUnit = "°C";
break;
case "Visibility":
thresholdUnit = "m";
break;
}
var startEndRiepilogo =
tws !== null && twe !== null ? "from: " + tws + " to: " + twe : "";
var phrase = a.Active
? a.Variable
? a.Variable === "Snow"
? a.CumulationTime
? "It's " +
(a.Operator === "<" ? "not" : "") +
" snowing by " +
a.CumulationTime / 60 +
" minutes"
: "It's " + (a.Operator === "<" ? "not" : "") + " snowing"
: (a.Variable === "LastData"
? "Station inactive "
: this.getOperatorString(a.Operator)) +
" " +
(a.Threshold
? this.transformThreshold(a.Threshold, a.Variable)
: "") +
" " +
thresholdUnit +
(a.CumulationTime
? " for " + a.CumulationTime / 60 + " minutes"
: "")
: null
: "Disabled";
var userIcon =
a.recipients.length === 0 ? null : a.recipients.length === 1 ? (
<Popup
trigger={<Icon name="user" />}
content="1 recipient selected"
inverted
/>
) : (
<Popup
trigger={<Icon name="users" />}
content={a.recipients.length + " recipients selected"}
inverted
/>
);
var stationIcon = a.Stations ? (
a.Stations.length === 0 ? null : a.Stations.length === 1 ? (
<Popup
trigger={<Icon name="tag" />}
content={a.Stations.length + " station"}
inverted
/>
) : (
<Popup
trigger={<Icon name="tags" />}
content={a.Stations.length + " stations"}
inverted
/>
)
) : null;
if (this.checkVariableFilter(a)) {
return (
<Card color={a.Active ? "green" : "red"}>
<Card.Content header>
<Label color={this.getAlertHeaderColor(a.Variable)}>
{a.Name}
</Label>
<Dropdown
icon="ellipsis horizontal"
className="icon float-right"
>
<Dropdown.Menu>
<Dropdown.Item
onClick={() => {
this.props.selectAlert(id);
this.props.toggleAlertModal();
}}
>
Edit
</Dropdown.Item>
<Dropdown.Item
onClick={() => {
this.cloneAlert(a);
}}
>
Clone
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Card.Content>
<Card.Content textAlign="center">
<div className="alert-icon p-1">
<i className={"wi " + this.getAlertIcon(a.Variable)} />
</div>
<Card.Description>{phrase}</Card.Description>
<Card.Meta>{startEndRiepilogo}</Card.Meta>
</Card.Content>
<Card.Content extra>
<div class="float-left">{userIcon}</div>
<div class="float-right">{stationIcon}</div>
</Card.Content>
</Card>
);
}
});
}
return (
<Card.Group>
<Card as="a" onClick={() => this.insertAlert()}>
<Card.Content header />
<Card.Content textAlign="center">
<div className="alert-icon p-1">
<Icon name="plus" />
</div>
<Card.Description>Add alert</Card.Description>
</Card.Content>
<Card.Content extra />
</Card>
{panels}
</Card.Group>
);
}
}
AlertsView.propTypes = {
getAlerts: PropTypes.func.isRequired,
toggleAlertModal: PropTypes.func.isRequired,
toggleRecipientsModal: PropTypes.func.isRequired,
selectAlert: PropTypes.func,
alerts: PropTypes.arrayOf(PropTypes.object),
stations: PropTypes.arrayOf(PropTypes.object),
isAuthenticated: PropTypes.bool,
alertModalIsOpen: PropTypes.bool,
selectedAlertId: PropTypes.string,
recipients: PropTypes.arrayOf(PropTypes.object)
};
const mapStateToProps = state => {
return {
alerts: state.alerts.data
};
};
export default connect(
mapStateToProps
)(AlertsView);