MobX React:如何仅重新渲染View的一部分

时间:2017-05-05 17:44:02

标签: reactjs mobx mobx-react google-maps-react

我有一个地图反应组件,我正在动态添加标记。问题是,当我在商店中添加标记时,整个地图会重新渲染而不是仅仅将标记附加到地图上。有人有任何关于如何解决这个问题的建议吗?我很确定我需要将商店专门注入CPMap函数,我只是不确定如何。

const CPMap = withGoogleMap((props) => (
        <GoogleMap
            ref={props.onMapLoad}
            style={{
                height: 100,
                width: 100,
            }}
            onCenterChanged={props.boundsChanged}
            defaultOptions={{ styles: this.mapStyles }}
            defaultZoom={props.zoom}
            defaultCenter={{ lat: props.center.lat, lng: props.center.lng }}>
            <MarkerClusterer
                gridSize={40}>
                {
                    props.markers.map(({ key, position }) => (
                        <Marker
                            key={key}
                            position={{ lat: position.lat, lng: position.lng }}
                            icon={{
                                url: require('../../images/marker.png')
                            }}
                        />
                    ))
                }
            </MarkerClusterer>
        </GoogleMap >
    ))

    return (
        <CPMap
            style={{
                height: 100,
                width: 100,
            }}
            onMapLoad={(gMap) => {
                map = gMap
                this.props.map.fetchMarkers()
            }}
            boundsChanged={() => {
                this.props.map.fetchMarkers()
            }}
            center={this.props.map.center}
            zoom={this.props.map.zoom}
            markers={mobx.toJS(this.props.map.markers)}
            containerElement={
                <div style={{ height: 'calc(100vh - 70px)' }
                } />
            }
            mapElement={
                <div style={{ height: 'calc(100vh - 70px)' }} />
            } />
    )
}

1 个答案:

答案 0 :(得分:0)

我建议您使用以下解决方案:不要将制造商直接传递给CMap组件,而是使用商店;

const markersStore = observable({
    markers: []
});

然后在你的组件中 - 将MarkersClusterer移动到单独的组件并传递markerStore更深一层:

//import markersStore or inject via mobx-react package
class MyComponent extends Component {
   render() {
      const CMap = withGoogleMap((props) => (
         <GoogleMap
            ...
            <Clusterer markersStore={props.markersStore} />
         />
      ))
      return (
         <CMap
            ...
            markersStore={markersStore}
         />
      )
   }
}

使您的新群集组件可观察,以便在markersStore&#34; marker&#34;财产更新;

@observable
class Clusterer extends Component {
    render(){
       const { markers } = this.props.markersStore;
       return (
          <MarkerClusterer>
              { markers.map(...)}
          </MarkerClusterer>
       )
    }
}

最后的更改是更新你的fetchMarkers方法,以便用新数据填充markersStore。

使用此解决方案,CMap组件对标记没有任何了解,并且在收到新数据时不会更新。与此同时,MarkersClusterer组件变得更加聪明,并且#34;观察&#34; markersStore中的变化。