我正在构建一个传单标记的传单地图。这些标记除了lat和long之外还有其他数据(在这种情况下为键)
我正在使用react-leaflet repo中的自定义反应组件。我可以获得多个标记位置,但是当我尝试检索我点击的标记并将其传递给子组件时我得到了
无法读取属性'#<对象> '未定义的
我可以传递所有数据,但没有问题。
当我尝试将"点击的" 标记传递给Card和Cartitle组件时,我收到此错误。
到目前为止我已尝试过:
在handleToggle函数中,我做了:
index = this.props.places [index]
但是当我得到上面的错误时。我做错了什么?
Pd积。此外,我能够将 ALL 数据显示给子组件
import ...
const markers = [
{
key: 'P12345678',
position: [37.786464, -122.411047],
children: 'My first popup'
},
{
key: 'M12345678',
position: [40.689192, -74.044563],
children: 'My second popup'
},
];
class Mapper extends Component {
constructor(props) {
super(props);
this.handleToggle = this.handleToggle.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = {
lat: 29.761993,
lng: -95.366302,
zoom: 4,
open: false,
places: []
}
}
handleToggle(index) {
const self = this;
self.setState({
open: !this.state.open,
places: markers
});
// index = this.props.places[index]
console.log(this.state.places)
}
handleClose() {
this.setState({
open: false
});
}
render() {
const center = [this.state.lat, this.state.lng];
//Custom Marker Component
const MyPopupMarker = ({ children, position }) => (
<Marker
onClick={this.handleToggle}
position={position}
places={this.state.places}
>
<Popup>
<span>{children}</span>
</Popup>
</Marker>
)
MyPopupMarker.propTypes = {
// children: MapPropTypes.func,
// position: MapPropTypes.latlng,
}
//Custom Marker List Component
const MarkerList = ({ markers }) => {
const items = markers.map(({ key, ...props }) => (
<MyPopupMarker key={key} {...props} />
))
return <div style={{display: 'none'}}>{items}</div>
}
MarkerList.propTypes = {
markers: MapPropTypes.array.isRequired,
}
// console.log('markers', markers)
return (
<div>
<Map
center={center}
zoom={this.state.zoom}
style={styles.map}>
<TileLayer
url='https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png'
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
<MarkerList markers={markers} />
</Map>
<Drawer
width={500}
openSecondary={true}
docked={false}
open={this.state.open}
onRequestChange={(open) => this.setState({open})}
containerStyle={styles.whitebox}
>
{
markers.map((cf, k) => (
<Card
style={styles.appMedia}
key={k}
>
<CardTitle
titleStyle={styles.drawTitle}
subtitleStyle={styles.drawTitle}
title={cf.key}
subtitle="Common Field Equipment"/>
</Card>
))
}
</Drawer>
</div>
);
}
}
export default Mapper;
答案 0 :(得分:1)
您的handleToggle
方法是onClick
组件的Marker
处理程序。 React中的onClick
处理程序默认传递一个合成事件对象(有关此here的更多信息)。
因此传递给index
方法的handleToggle
将是合成事件对象,这无法帮助您从places
数组中获取标记的索引。您必须将索引显式传递到handleToggle
方法中。为此,您需要进行以下更改:
1&GT;将构造函数中函数的绑定更改为:
this.handleToggle = this.handleToggle.bind(this,index);
2 - ;在MyPopupMarker
组件中明确传递索引:
const MyPopupMarker = ({ children, position,index }) => (
<Marker
onClick={()=>this.handleToggle(index)}
....
)
3&GT;将索引传递给MyPopupMarker
组件
MarkerList
组件
const items = markers.map(({ key, ...props },i) => (
<MyPopupMarker key={key} index={i} {...props}/>
))
4&GT;从places
对象中的state
数组而不是props
对象访问索引。
handleToggle(index) {
const self = this;
self.setState({
open: !this.state.open,
places: markers
});
var selectedMarker = this.state.places[index];
console.log(this.state.places)
}
错误消息的原因无法读取属性'#&lt;对象&gt; “未定义是您尝试访问places
props
对象中的undefined
数组。
顺便说一句,我想指出在render
方法(组件MyPopupMarker
和MarkerList
)中创建组件不是一个好习惯,因为这些组件会被创建在每一个浪费的渲染上。如果您在Mapper
组件之外声明它们会更有效率。
修改强>
要将组件移出render
,您需要将handleToggle
函数作为props
传递。我已按如下方式更改了您的代码:
MyPopupMarker组件:此组件将index
和handleToggle
函数作为道具。
const MyPopupMarker = ({ children, position, index, handleToggle }) => (
<Marker onClick={() => handleToggle(index)} position={position}>
<Popup>
<span>{children}</span>
</Popup>
</Marker>
);
MarkerList组件:此组件将handleToggle
函数作为道具获取,并将其与MyPopupMarker
index
组件
const MarkerList = ({ markers, handleToggle }) => {
const items = markers.map(({ key, ...props }, i) => (
<MyPopupMarker key={key} {...props} index={i} handleToggle={handleToggle} />
));
return <div >{items}</div>;
};
Mapper组件:此组件将handleToggle
函数与MarkerList
markers
组件
class Mapper extends Component {
constructor(props) {
super(props);
this.handleToggle = this.handleToggle.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = {
lat: 29.761993,
lng: -95.366302,
zoom: 4,
open: false,
places: []
};
}
handleToggle(index) {
const self = this;
self.setState({
open: !this.state.open,
places: markers
});
// index = this.props.places[index]
let selectedMarker = this.state.places[index];
console.log(selectedMarker);
}
handleClose() {
this.setState({
open: false
});
}
render() {
const center = [this.state.lat, this.state.lng];
let selectedMarker = this.state.places;
return (
<div>
<Map center={center} zoom={this.state.zoom} style={styles.map}>
<TileLayer
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
/>
<MarkerList markers={markers} handleToggle={this.handleToggle} />
</Map>
<Drawer
width={500}
openSecondary={true}
docked={false}
open={this.state.open}
onRequestChange={open => this.setState({ open })}
containerStyle={styles.whitebox}
>
{selectedMarker.map((value, index) => (
<Card style={styles.appMedia} key={index}>
<CardTitle
titleStyle={styles.drawTitle}
subtitleStyle={styles.drawTitle}
title={value.key}
subtitle="Common Field Equipment"
/>
</Card>
))}
</Drawer>
</div>
);
}
}
export default Mapper;
找到完整的工作示例