2017-09-19 29 views
7

最近我一直對此感到莫名其妙,而且我正在根據地圖標記是否被選中/活動來動態更新地圖標記圖像(每個MapMarker都有一個類別,其中引用了活動圖像或默認圖像來自兩個圖像集合interestIcons和interestIconsSelected從本質上講,我有一個MapMarkers集合,通過映射標記集合進行渲染,每個MapMarker都是MapView.Marker的子組件。所有MapMarkers都處於默認非選定/非活動狀態,其中有來自interestIcons的默認圖像,當選中時,MapMarker圖像應該改變爲來自interestIconsSelected的活動圖像,當選擇另一個MapMarker時,上一次選擇應該恢復爲默認圖像和新的應該改變爲選定的圖像。如何根據選擇與否來動態更新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> 

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} 
      /> 
     ) 
    } 
} 

的componentWillReceiveProps(nextProps)仍然是一項正在進行的工作,並表示「足夠好」時,當前選定的事件和人的非選定的事件。

我已經嘗試設置圖像源使用說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} 
      /> 
     ) 
    } 
} 

更改圖像狀態似乎確實在該圖像會立即改變更有效地工作,但似乎初始渲染中的圖像根本不會被設置,所以在選擇之前它只是一個空圖標。

非常感謝,感謝任何幫助。

更新:試圖在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> 
) 

但是這個工作雖然你似乎沒有能夠將樣式應用到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]]} 
    /> 
) 

以上兩個使用MapView.Marker直接使用圖像道具或直接在MapView.Marker下使用Image組件的代碼snipets與使用MapMaper子組件不同。

回答

1

您使用componentWillReceiveProps生命週期法並沒有跑在第一渲染也使用this.state.initialized與在constructor狀態false,所以這會使你需要兩次點擊,使它活動

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}); 
    } 
    ....... 
} 

可以徹底刪除您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]]; 
} 

這裏你比較具有相同比較兩個對象爲深,你可以使用一些像這樣的事情,而不是就拿不到通天CON融合see more

<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} 
/> 

我希望幫助謝謝

+0

感謝您的回答穆罕默德,請參閱我的編輯。看起來,如果您使用MapView.Marker的圖像道具,圖像會動態變化,但它甚至不會說出諸如'this.props.selected.id === this.props.event 。ID ? interestIconsSelected [this.props.event.interest [0]]:interestIcons [this.props.event.interest [0]]; –

+0

你能爲此創建一個快速回購嗎?你是否確定這不是一個造型問題,像一個沒有按下的標記? –

+0

,因爲自定義標記在造型上很棘手 –

相關問題