我正在将项目列表转换为动态下拉选项列表,但我遇到了问题。
我检查了props是否正确,它们是。
这是转换列表的一段代码:
buildSelectOptions = (opts) => {
return opts.map((opt) => <Option value={opt.id}>{opt.uid}</Option>)
};
render() {
const {allKeycodes} = this.props.allKeycodes;
console.log(allKeycodes);
const allKeycodesOptions = this.buildSelectOptions(allKeycodes);
}
如果您在理解问题时遗漏了任何内容,我很抱歉,我已准备好告诉您理解此问题所需的任何内容。
错误说:无法读取未定义的属性“地图”
这是完整的代码:
import React, {Component} from "react";
import {Modal, Tabs, Row, Col, Button, Alert, Select} from "antd";
import {saveAs} from "file-saver";
import JSZip from "jszip";
import styled from "styled-components";
import moment from "moment";
import TableComponent from "components/Shared/TableComponent";
import logo from "assets/images/homeKeyLogoSign.png";
import keycodesImage from "assets/images/Logo_HomeKey.png";
import keycodesImageBW from "assets/images/Homekey-bw.PNG";
const {TabPane} = Tabs;
const Option = Select.Option;
const StyledModal = styled(Modal)`
input {
height: 50px !important;
}
padding: 10px !important;
`;
const LeftPanel = styled.div`
margin:auto;
text-align:center;
`;
const StyledImg = styled.img`
height:150px;
width:150px;
margin:auto;
margin-bottom: 20px !important;
`;
const Label = styled.p`
margin:auto;
text-transform: uppercase;
font-size:0.9em;
margin-top: 5px !important;
color: #858585;
padding-left: 20px;
font-family: 'Work Sans', sans-serif;
`;
const Title = styled.h1`
color: #25B0FF;
font-size: 30px;
font-family: 'Nunito', sans-serif !important;
font-weight: bold;
text-align: left;
margin-left: 15px !important;
`;
const Value = styled.p`
margin:auto;
text-transform: uppercase;
font-size:1em;
margin-top: 5px !important;
margin-bottom: 10px !important;
color: #000000;
font-weight: 500;
padding-left: 20px;
font-family: 'Work Sans', sans-serif;
`;
const ScansBox = styled.div`
margin:auto;
background-color: #F5F5F5;
min-height:20px;
width:250px;
`;
const ScanLabel = styled.p`
font-size:1em;
text-transform: uppercase;
padding-top: 15px;
font-family: 'Work Sans', sans-serif;
`;
const ScanValue = styled.h1`
color: #25B0FF !important;
font-size:4em;
font-weight: 200;
padding-bottom: 15px;
font-family: 'Nunito', sans-serif !important;
font-weight: bold;
`;
const DefaultButton = styled(Button)`
margin:auto;
background: #25B0FF !important;
color: white !important;
font-weight: 300 !important;
padding: 0 40px !important;
min-height: 50px;
width:250px;
text-transform: uppercase;
margin-bottom: 10px !important;
font-family: 'Nunito', sans-serif !important;
font-weight: bold !important;
margin-top: 15px;
`;
const DefaultButtonWhite = styled(Button)`
margin:auto;
color: #25B0FF !important;
font-weight: 300 !important;
padding: 0 40px !important;
min-height: 50px;
width:250px;
text-transform: uppercase;
margin-bottom: 10px !important;
font-family: 'Nunito', sans-serif !important;
font-weight: bold !important;
border:1px solid #25B0FF !important;
`;
const StatusSection = styled.div`
min-height:130px;
background-color: #FFFFFF;
border-radius:10px;
`;
const StatusContent = styled.div`
height:570px;
background-color: #EEF2F6;
padding: 20px 20px 20px 20px;
`;
const ResidenceDetailsSection = styled.div`
min-height:385px;
background-color: #FFFFFF;
border-radius:10px;
margin-top: 20px;
`;
const DetailsHeader = styled.h1`
margin: 20px;
font-size: 1.5em
color: #25B0FF !important;
font-family: 'Nunito', sans-serif !important;
font-weight: bold;
`;
const StyledAlert = styled(Alert)`
margin-bottom: 20px !important;
`;
const StyledSelectInput = styled(Select)`
margin-bottom: 5px !important;
height: 50px !important;
.ant-select-selection--single {
height: 50px !important;
}
.ant-select-selection__rendered {
line-height: 50px !important;
}
font-family: 'Work Sans', sans-serif;
min-width: 250px;
`;
const columns = [{
title: "Date & Time",
dataIndex: "scan.createdAt",
key: "DateTime",
}, {
title: "UserID",
dataIndex: "device.userId",
key: "UserID",
}, {
title: "Version",
dataIndex: "device.appVersion",
key: "Version"
}, {
title: "OS",
dataIndex: "device.deviceOS",
key: "OS",
}, {
title: "Device",
dataIndex: "device.deviceType",
key: "Device",
}];
class HomeDetails extends Component {
constructor(props) {
super(props);
this.state = {
loadingDownload: false,
error: null
};
this.state = {assignKeycodeCkicked: false};
}
onTabsChange = (key) => {};
formatStatus = (status) => {
let formattedStatus = status.charAt(0).toUpperCase() + status.slice(1);
return formattedStatus.replace(/[_-]/g, " ");
};
handleAssignKeycodesClick() {
this.setState({assignKeycodeCkicked: 'true'});
}
downloadSvgAndPng = (keycodeUID) => {
this.setState({loadingDownload: true});
const zip = new JSZip();
const requests = ['svg', 'png'].map((ext) => this.props.getKeycodeImage(keycodeUID, ext).then((response) => ({
ext,
file: response
})));
Promise.all(requests)
.then((responses) => Promise.all(responses.map((response) => zip.file(`${keycodeUID}.${response.ext}`, response.file))))
.then(() => zip.generateAsync({type:"blob"}))
.then((zipFile) => {
saveAs(zipFile, `keycode-${keycodeUID}-images.zip`);
this.setState({loadingDownload: false});
}).catch((error) => {
console.log(error);
this.setState({loadingDownload: false, error: `No images found for keycode: ${keycodeUID}`})
})
};
buildSelectOptions = (opts) => {
return opts.map((opt) => <Option value={opt.id}>{opt.uid}</Option>)
};
selectFilterOptions = (input, option) => {
return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
};
render() {
const data = this.props.data || {keycode: {}, builder: {}, community: {}, home: {}};
const keyCodeScans = this.props.keycodeScans || {count: 0, scans: []};
const lastKeycodeScan = keyCodeScans.scans[0] ? moment(keyCodeScans.scans[0].scan.createdAt).format("MMM DD, YYYY - HH:mm") : "--";
this.handleAssignKeycodesClick = this.handleAssignKeycodesClick.bind(this);
const {allKeycodes} = this.props.allKeycodes;
const allKeycodesOptions = this.buildSelectOptions(allKeycodes);
const AssigneKeycode = this.state.assignKeycodeCkicked;
console.log(allKeycodes)
return (
<StyledModal
visible={this.props.visible}
onOk={this.props.closeModal}
onCancel={this.props.closeModal}
footer={null}
width={900}
centered
>
<Tabs defaultActiveKey="tab-2" onChange={this.onTabsChange}>
<TabPane tab={<img alt="homeKeyLogo" src={logo}/>} disabled key="tab-1"/>
<TabPane tab="DETAILS" selected key="tab-2">
<Row>
{this.state.error && <StyledAlert message={this.state.error} type="error"/>}
</Row>
<Row>
{AssigneKeycode ?
<Col span={8}>
<LeftPanel>
<StyledImg className="logo" alt="homeKeyLogo" src={keycodesImageBW}/>
<Title>Are you sure you want to assign a new KeyCode?</Title>
<StyledSelectInput
showSearch
placeholder="Select a keycode id"
optionFilterProp="children"
>
</StyledSelectInput>
<DefaultButton>Assign new keycode</DefaultButton>
<DefaultButtonWhite>cancel</DefaultButtonWhite>
</LeftPanel>
</Col>
:
<Col span={8}>
<LeftPanel>
<StyledImg className="logo" alt="homeKeyLogo" src={keycodesImage}/>
<Label>Keycode Id</Label>
<Value>{data.keycode.uid}</Value>
<Label>Batch</Label>
<Value>{data.keycode.keycodeBatchId || "--"}</Value>
<ScansBox>
<ScanLabel>Total Scans</ScanLabel>
<ScanValue>{keyCodeScans.count || 0}</ScanValue>
</ScansBox>
<DefaultButton onClick={() => this.downloadSvgAndPng(data.keycode.uid)} loading={this.state.loadingDownload}>Download Svg & Png</DefaultButton>
<DefaultButton onClick={this.handleAssignKeycodesClick}>Assign New Keycode</DefaultButton>
</LeftPanel>
</Col>
}
<Col span={16}>
<StatusContent>
<Row>
<StatusSection>
<Col span={12}>
<DetailsHeader>Status</DetailsHeader>
<Label>Keycode assigned on</Label>
<Value>{data.keycode.assignedAt ? moment(data.keycode.assignedAt).format("MMM DD, YYYY - HH:mm") : "--"}</Value>
</Col>
<Col span={12}>
<DetailsHeader>{data.keycode.status ?
this.formatStatus(data.keycode.status)
: "--"
}</DetailsHeader>
<Label>Last Scan</Label>
<Value>{lastKeycodeScan}</Value>
</Col>
</StatusSection>
</Row>
<Row>
<ResidenceDetailsSection>
<Row>
<DetailsHeader>Residence Details</DetailsHeader>
<Label>Address</Label>
<Value>{data.home.fullAddress || "--"}</Value>
</Row>
<Col span={12}>
<Label>Builder</Label>
<Value>{data.builder.companyName}</Value>
<Label>Residence Type</Label>
<Value>{data.home.homeType}</Value>
</Col>
<Col span={12}>
<Label>Community</Label>
<Value>{data.community.name}</Value>
<Label>Activated On</Label>
<Value>{data.keycode.activatedAt || "--"}</Value>
</Col>
</ResidenceDetailsSection>
</Row>
</StatusContent>
</Col>
</Row>
</TabPane>
<TabPane tab="HISTORY" key="tab-3">
<Row>
<Col span={24}>
<TableComponent columns={columns}
dataSource={keyCodeScans.scans}
rowKey="id"
loading={false}
onChange={(page, size) => this.props.getKeycodeScans(data.keycode.id, page, size)}
count={keyCodeScans.count}
/>
</Col>
</Row>
</TabPane>
</Tabs>
</StyledModal>
);
}
}
export default HomeDetails;
控制台日志中的 allKeycodes 对象:
(500) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]
[0 … 99]
0: {id: 10, uid: "1000000000000010", pngLocation: null, svgLocation: null, status: "unassigned", …}
1: {id: 9, uid: "1000000000000009", pngLocation: null, svgLocation: null, status: "ready_to_ship", …}
2: {id: 8, uid: "1000000000000008", pngLocation: null, svgLocation: null, status: "blank", …}
3: {id: 7, uid: "1000000000000007", pngLocation: null, svgLocation: null, status: "ready_to_ship", …}
4: {id: 6, uid: "1000000000000006", pngLocation: null, svgLocation: null, status: "installed", …}
5: {id: 5, uid: "1000000000000005", pngLocation: null, svgLocation: null, status: "installed", …}
6: {id: 4, uid: "1000000000000004", pngLocation: null, svgLocation: null, status: "activated", …}
7: {id: 3, uid: "1000000000000003", pngLocation: null, svgLocation: null, status: "blank", …}
8: {id: 2, uid: "1000000000000002", pngLocation: null, svgLocation: null, status: "unassigned", …}
9: {id: 1, uid: "1000000000000001", pngLocation: null, svgLocation: null, status: "activated", …}
10: {id: 20, uid: "1000000000000020", pngLocation: null, svgLocation: null, status: "ready_to_ship", …}
11: {id: 19, uid: "1000000000000019", pngLocation: null, svgLocation: null, status: "assigned", …}
12: {id: 18, uid: "1000000000000018", pngLocation: null, svgLocation: null, status: "installed", …}
13: {id: 17, uid: "1000000000000017", pngLocation: null, svgLocation: null, status: "blank", …}...```