即使数据未更改,传单群集标记也会重新呈现并关闭打开的蜘蛛

Leaflet cluster marker re-renders and closes open spider even though data was not changed

我在 React 应用程序中有一个 Leaflet 地图,我正在使用 react-leaflet-markercluster 来聚类完全相同坐标上的标记。

我也有一个请求,我每 5 秒发出一次获取标记的请求,它们大多是相同的标记,但是,当点击一个集群标记时,5 秒后,所有标记都会重新呈现,并且蜘蛛关闭。

你可以试试看这个demo(点击等待,蜘蛛关闭): https://stackblitz.com/edit/cluster-keeps-rerendering

有人知道如何解决这个问题吗?

这是预期的行为,因为在您的示例中,正在创建 markers 数组的 deep 副本:

   this.setState(prevState => ({
        markers: prevState.markers.map(marker => ([ ...marker ]))
      }));

来自 shouldComponentUpdate documentation:

PureComponent performs a shallow comparison of props and state, and reduces the chance that you’ll skip a necessary update.

意思是每次 markers 状态改变时 Map 组件得到 re-rendered.

考虑创建 markers 数组的 浅层 副本,例如:

const newMarkers = [...this.state.markers];
this.setState(prevState => ({
    markers: newMarkers
}));

或通过 shouldComponentUpdate lifecycle method 执行 自定义比较 ,以下示例演示如何通过比较 [=] 来防止 MarkerClusterGroup 来自 re-rendering 13=] 坐标已更改:

class MarkerList extends React.Component {

  shouldComponentUpdate(nextProps, nextState) { 
      const markers = nextProps.markers.filter((m, i) => this.props.markers[i][0] !== m[0] || this.props.markers[i][1] !== m[1]); 

     return markers.length > 0;
  } 

  render() {
    return (
        <MarkerClusterGroup
          showCoverageOnHover={false}
          maxClusterRadius={0}
        >
          {this.props.markers.map((marker, index) => (
            <Marker position={marker} key={index} />
          ))}
        </MarkerClusterGroup>
    );
  }
}  

Here is 一个分叉的例子

备注

通常不推荐这种方法,因为它可能会导致错误,React 文档在这方面说明如下:

We do not recommend doing deep equality checks or using JSON.stringify() in shouldComponentUpdate(). It is very inefficient and will harm performance.