Mic*_*kes 8 reactjs react-native airbnb-js-styleguide react-native-maps
最近我一直对此感到困惑,我希望根据是否选择/激活地图标记来动态更新地图标记图像(每个MapMarker都有一个类别引用活动图像或默认图像来自两个图像集合:interestIcons和interestIconsSelected.基本上我有一个MapMarkers集合,它们通过map标记集合进行映射.每个MapMarker都是MapView.Marker的子组件.
我想将所有MapMarkers渲染为默认的非选择/非活动状态,其中包含来自interestIcons的默认图像,当选中时,MapMarker图像应该从interestIconsSelected更改为活动图像,当选择另一个MapMarker时,之前选择的应该是恢复为默认图像,新的应更改为所选图像.
目前,我能够使用默认图像渲染地图标记,但是当选择地图标记时,图像似乎不会立即更改,除非您再次缩小/放大,即导致某种重新渲染,我想这样点击MapMarker会立即导致图像更新.
MapScreen.js: 通过地图渲染所有MapView.Marker MapMarkers的MapView.
<MapView
ref={map => { this._map = map }}
style={Styles.Map.map}
initialRegion={this.props.region}
onRegionChange={this.handleRegionChange}
>
{
this.props.events
.filter(this.eventFilterTimeNearFuture)
.filter(this.eventFilterTimeNotPast)
.filter(this.eventFilterDistance)
.filter(this.eventFilterInterest)
.map(e =>
<MapView.Marker
key={e.id}
onPress={() => this.handleLocationPush(e)} // Set selected event state
coordinate={e.location}
>
<MapMarker
event={e}
size={this.state.markerSize}
selected={this.state.selectedEvent} // The selected event set by state call.
/>
</MapView.Marker>
)
}
{ !this.props.regionMock &&
<MapView.Marker
key={'userLocation'}
coordinate={this.props.region}
>
<MapMarker size={'user'} />
</MapView.Marker>
}
</MapView>
Run Code Online (Sandbox Code Playgroud)
MapMarker.js
import {interestIcons, interestColors, interestIconsSelected} from "../../utils/Icons";
import {Styles} from '../../StyleProvider';
class MapMarker extends React.Component {
constructor() {
super();
this.state = {
initialized: false,
active: false,
};
};
componentWillReceiveProps(nextProps) {
if (!this.state.initialized) {
console.log('initialization');
this.setState({initialized: true});
}
else {
// If the nextProps.selected prop exists which it will
if (nextProps.selected) {
// If the nextProps.selected props id equals the this event id then selected else non-selected.
if (nextProps.selected.id === nextProps.event.id) {
console.log('SELECTED: ' + JSON.stringify(nextProps.selected));
// set staae to active
this.setState({
active: true
});
console.log(interestIconsSelected[nextProps.event.interest[0]]);
} else {
// set state to not active
// console.log('NON-SELECTED: ' + JSON.stringify(nextProps.event));
this.setState({
active: false
});
}
this.forceUpdate();
}
}
}
markerIcon(interest) {
return this.state.active ? interestIconsSelected[interest] : interestIcons[interest];
}
renderIcon() {
if (this.props.event.type === 'Event') {
return (
<Image
source={this.markerIcon(this.props.event.interest[0])}
style={Styles.MapMarker.eventImage}
/>
)
}
}
Run Code Online (Sandbox Code Playgroud)
componentWillReceiveProps(nextProps)仍然是正在进行的工作,它表示当前所选事件和非选定事件的"足够好".
我试图将图像源设置为使用say this.state.image
然后分别在componentWillReceiveProps中设置图像状态,即
if (nextProps.selected) {
// If the nextProps.selected props id equals the this event id then selected else non-selected.
if (nextProps.selected.id === nextProps.event.id) {
console.log('SELECTED: ' + JSON.stringify(nextProps.selected));
// set staae to active
this.setState({
active: true,
image: this.markerIcon(nextProps.event.interest[0], true)
});
console.log(interestIconsSelected[nextProps.event.interest[0]]);
} else {
// set state to not active
console.log('NON-SELECTED: ' + JSON.stringify(nextProps.event));
this.setState({
active: false,
image: this.markerIcon(nextProps.event.interest[0], false)
});
}
}
renderIcon() {
if (this.props.event.type === 'Event') {
return (
<Image
source={this.state.image}
style={Styles.MapMarker.eventImage}
/>
)
}
}
Run Code Online (Sandbox Code Playgroud)
更改图像状态似乎确实更有效,因为图像会立即更改,但似乎初始渲染中的图像根本不会被设置,因此它将只是一个空图标,直到被选中.
非常感谢,感谢任何帮助.
更新:尝试在MapView.Marker下定义Image组件,但这不起作用.
this.state.markers
.map(e =>
<MapView.Marker
key={e.id}
onPress={() => this.handleLocationPush(e)}
coordinate={e.location}
>
{/* <MapMarker
event={e}
size={this.state.markerSize}
/> */}
<Image
source={this.state.selectedEvent === e ? interestIconsSelected[e.interest[0]] : interestIcons[e.interest[0]]}
style={Styles.MapMarker.eventImage}
/>
</MapView.Marker>
)
Run Code Online (Sandbox Code Playgroud)
但是这可行,虽然您似乎无法将样式应用于MapView.Marker,但这不是我想要的实现,因为我想保留自定义MapMarker组件
this.state.markers
.map(e =>
<MapView.Marker
key={e.id}
onPress={() => this.handleLocationPush(e)}
coordinate={e.location}
image={this.state.selectedEvent === e ? interestIconsSelected[e.interest[0]] : interestIcons[e.interest[0]]}
/>
)
Run Code Online (Sandbox Code Playgroud)
以上两个代码的snipets使用MapView.Marker上的image prop或者直接在MapView.Marker下使用Image组件并不像使用MapMaper子组件那样好.
您使用componentWillReceiveProps
生命周期方法,它在第一次渲染时没有运行,您也使用状态this.state.initialized
为 false 的方法 constructor
,因此这将使您需要两次单击才能使其处于活动状态
componentWillReceiveProps(nextProps) { // it did not run at first render
if (!this.state.initialized) { // this.state.initialized with is false in constructor
console.log('initialization');
this.setState({initialized: true});
}
.......
}
Run Code Online (Sandbox Code Playgroud)
componentWillReceiveProps
如果你这样做,你可以完全删除你的
markerIcon() { //did not get interest directly instead access it from props
return this.props.selected.id === this.props.event.id ?
interestIconsSelected[this.props.event.interest[0]]
:
interestIcons[this.props.event.interest[0]];
}
Run Code Online (Sandbox Code Playgroud)
在这里,您比较两个具有相同比较的对象,因为它们很深,您可以使用类似这样的东西,而不是让 babel 感到困惑查看更多
<Image
// use this.state.selectedEvent.id === e.id instead of this.state.selectedEvent === e
source={this.state.selectedEvent.id === e.id ? interestIconsSelected[e.interest[0]] : interestIcons[e.interest[0]]}
style={Styles.MapMarker.eventImage}
/>
Run Code Online (Sandbox Code Playgroud)
我希望有帮助谢谢
归档时间: |
|
查看次数: |
624 次 |
最近记录: |