我正在使用redux来管理我的应用状态,并使用Google地图(或其他地图)来显示我的数据。
我有一个非常复杂的UI,并希望通过redux对其进行管理。但是我在下面有一个问题:
map.panBy(-10,-20)
,结果是中心将被更改,但是通过执行panBy
会有动画,在这种情况下(-10, -20)
不是结果,它只是偏移量,因此将其(偏移量)保存在商店中并不是一个好主意。我该怎么办?Solution I
:使用redux数据流,调度类似{type:'panBy', payload: [-10, -20]}
的操作,当组件B获取数据时,执行map.panBy(-10,-20)
。 -> -10,-20是临时参数,存储起来很奇怪。Solution II
:Eventbus,组件A触发事件和组件B对其进行订阅。Solution III
:将map
暴露给它的父对象或window
对象。 ->也很奇怪... 那么,有解决此问题的通用解决方案吗?
我可以使用redux中间件吗?但是中间件DONOT也知道map
。
答案 0 :(得分:1)
如果我对您的理解正确:
您的问题有一点不清楚-是panBy参数是否是您在redux状态下存储的数据。
将以redux状态存储这些参数有点奇怪,因为这些是您一次执行的更多操作,而不是事物的客观数据。
我的意思是-我想您将要存储在状态中的数据类型将是诸如“名称”,“地址”,“纬度”之类的数据,应用这些数据时,它们看起来总是一样。每次您显示“平移”数据时,其显示方式将有所不同。
但是无论如何-如果您只是显示/应用处于redux状态的内容-我将要做的是:
但是回到panBy的事情-我建议您应该存储地图中心和缩放级别,而不是存储panBy参数。这样,每次应用时它看起来都一样。
或者,您可以存储原始中心和 panBy参数,并使用它们每次重新计算地图。
即。 redux状态如下:
mapState: {
center: {
x: 100,
y: 200,
},
panBy: {
x: 10,
y: 0
}
}
,然后在您的componentDidUpdate
中将其更新-并应用平底锅,例如:
componentDidUpdate(prevProps) {
if (this.props.mapState !== prevProps.mapState) {
const {mapState} = this.props.mapState;
Map.center(mapState.center);
Map.panBy(mapState.panBy);
}
}
这样做的缺点-每次都需要冗余地重新映射地图,并且根据API的工作方式,它看起来可能很糟糕。
我确实认为更好的解决方案是自己手动重新计算中心-如Spark.Bao所建议。
答案 1 :(得分:1)
同意@dwjohnston,您应该保存喜欢中心的状态并放大redux商店,您的地图至少应具有初始中心,对,该值应为初始状态,例如:
const initialState = {
center: {
lat: 100,
lng: 100
},
zoom: ...
}
function mapOptions(state = initialState, action) {
switch(action.type) {
...
}
}
分派操作后,减速器应根据有效负载修改状态(操作应为{type: "panBy", payload: [-10, -20]}
):
function mapOptions(state = initialState, action) {
switch(action.type) {
case "panBy":
const offset = action.payload
return {
...state,
center: {
lat: state.center.lat + offset[0],
lng: state.center.lng + offset[1]
}
}
}
}
然后您的组件B应该通过新状态更新地图中心。
不知道A组件和B组件分开多远,如果A组件在B组件内部,则从A调用use回调直到到达B,例如:
class A extends React.Component {
render() {
<button onClick={()=>this.props.moveMap(-10, -20)}>Move</button>
}
}
class B extends React.Component {
componentDidMount() {
this.map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
}
handleMoveMap = (offsetLng, offsetLat) => {
this.map.panBy(offsetLng, offsetLat)
}
render() {
<div>
<div id="map"/>
<A moveMap={this.handleMoveMap}/>
</div>
}
}
否则,您可以选择Solution III
,它可以工作并且更方便,但是它不是React模式(数据驱动器UI),而是jQuery模式(手动操作DOM)。 (有时我在React项目中也使用jQuery模式)。
在React和Redux思维中,您应该将共享数据按不同组件放入redux存储中。